SlideShare ist ein Scribd-Unternehmen logo
1 von 36
A topology of
memory leaks on the JVM
HotSpot JVM process
heap perm gen
native
stack
C
sta.
user
managed
string
pool
method
area
pc
reg.
code
cache
young
gen
ten.
gen
const.
pool
e
d
e
n
s
r
.
1
s
r
.
2
-Xms
-Xmx
-Xss
-Xsx
-XX:PermSize
-XX:MaxPermSize
(operating system)
Java 6 -> 7
Java 7 -> 8
genuine leaks
HotSpot JVM process
heap perm gen
native
stack
C
sta.
user
managed
string
pool
method
area
pc
reg.
code
cache
young
gen
ten.
gen
const.
pool
e
d
e
n
s
r
.
1
s
r
.
2
Field unsafe = Unsafe.class
.getDeclaredField("theUnsafe");
unsafe.setAccessible(true);
Unsafe theUnsafe = (Unsafe) unsafe.get(null);
Allocating native memory with sun.misc.Unsafe
1. Getting hold of “the unsafe“
2. Allocating native memory
final int intSize = 4;
long arraySize = (1L + Integer.MAX_VALUE) * intSize;
long index = unsafe.allocateMemory(arraySize);
Random random = new Random();
for(long l = 0L; l < arraySize; l++)
unsafe.putInt(random.nextInt());
3. (Hopefully) releasing native memory
// Without me, the memory leaks
unsafe.freeMemory(index);
I don‘t do sun.misc.Unsafe
1. But some of your favorite tools do:
1. Kryo (used by e.g. Twitter‘s Storm, Apache Hive)
2. EhCache‘s “big memory“ (used by e.g. Hibernate)
3. JDK (e.g. direct byte buffers)
4. General purpose (e.g. GSON, Snappy)
2. Unsafe to become public API in Java 9 (competition with CLR?)
3. JNI leaks have the same effect
4. Java 8 removes “perm gen“ in favor of native
memory “meta space“
symptoms of a genuine leak
No exception required by JVMS. However, JVM will be untypical slow when:
1. Creating a thread:
Requires allocation of new stacks / pc register.
2. Loading a class / JIT:
Requires native memory.
3. Doing I/O:
Often requires native memory.
4. Calling a native method:
Allocates resources on native stack / user space. Swapping can delay
execution.
5. Garbage collection:
Tenured generation collection needs broad access such that OS
must swap back the heap. Rule of thump: All JVM heaps must be
swapped back into memory. (Leaked memory will stay swapped out.)
Heap leaks
HotSpot JVM process
heap perm gen
native
stack
C
sta.
user
managed
string
pool
method
area
pc
reg.
code
cache
young
gen
ten.
gen
const.
pool
e
d
e
n
s
r
.
1
s
r
.
2
class FixedSizeStack {
private final Object[] objectPool = new Object[10];
private int pointer = -1;
public Object pop() {
if(pointer < 0)
throw new NoSuchElementException();
return objectPool[pointer--];
}
public Object peek() {
if(pointer < 0)
throw new NoSuchElementException();
return objectPool[pointer];
}
public void push(Object object) {
if(pointer > 8)
throw new IllegalStateException("stack overflow");
objectPool[++pointer] = object;
}
}
Element 5
Element 4
Element 3
Element 2
Element 1
Element 0
Stack
All memory leaks in Java are linked to reference life cycles.
Immutable Stack Element 0
Immutable Stack Element 1
Immutable Stack Element 2
public String substring(int beginIndex, int endIndex) {
// omitted argument validation
return ((beginIndex == 0) && (endIndex == count))
? this
: new String(offset + beginIndex,
endIndex - beginIndex,
value);
}
String(int offset, int count, char[] value) {
this.value = value;
this.offset = offset;
this.count = count;
}
JDK 6
XML, anybody?
org.xml.sax.DocumentHandler {
// several callback methods
void characters(char[] ch, int start, int length);
}
Webpage character blob
DocumentHandler few letter word
is defined by
produces
handles
public String substring(int beginIndex, int endIndex) {
// omitted argument validation
int subLen = endIndex - beginIndex;
return ((beginIndex == 0) && (endIndex == value.length))
? this
: new String(value, beginIndex, subLen);
}
public String(char[] value, int offset, int count) {
// omitted argument validation
this.value = Arrays.copyOfRange(value,
offset,
offset + count);
}
JDK 7
interface Message extends Serializable {
String getInfo();
}
class ExampleActivity extends Activity {
@Override public void onCreate(Bundle bundle) {
startService(
new Intent(this, getClass())
.putExtra(
"foo",
new Message() {
@Override public String getInfo() {
return "bar";
}
}));
}
}
A classic Android leak
class ExampleActivity$1 implements Message {
private ExampleActivity this$0;
ExampleActivity$1(ExampleActivity this$0) {
this.this$0 = this$0;
}
@Override public String getInfo() {
return "bar";
}
}
new Message() {
@Override public String getInfo() {
return "bar";
}
}
uncompiled
desugared
Non-static inner classes
class Foo {
void bar() {
List<String> list = Arrays.asList("foo", "bar");
list.forEach(LambdaMetafactory
.INVOKEDYNAMIC(Foo::lambda$1)
.make());
}
private static void lambda$1(String s) {
System.out.println(s);
}
}
class Foo {
void bar() {
List<String> list = Arrays.asList("foo", "bar");
list.forEach(s -> { System.out.println(s); });
}
}
uncompiled
desugared
Java 8 lambda expressions
class Foo {
final String prefix; // constructor omitted
void bar() {
List<String> list = Arrays.asList("foo", "bar");
list.forEach(s -> { System.out.println(
prefix + ":" + s) });
}
}
uncompiled
desugared
Java 8 lambda expressions
class Foo {
final String prefix; // constructor omitted
void bar() {
List<String> list = Arrays.asList("foo", "bar");
list.forEach(LambdaMetaFactory
.INVOKEDYNAMIC(this::lambda$1)
.make());
}
private void lambda$1(String s) {
System.out.println(this.prefix + ":" + s);
}
}
uncompiled
desugared
class Foo {
final String prefix; // constructor omitted
void bar() {
List<String> list = Arrays.asList("foo", "bar");
String prefix = this.prefix;
list.forEach(s -> { System.out.println(
prefix + ":" + s)});
}
}
class Foo {
final String prefix; // constructor omitted
void bar() {
List<String> list = Arrays.asList("foo", "bar");
String prefix = this.prefix;
list.forEach(LambdaMetafactory
.INVOKEDYNAMIC(Foo::lambda$1)
.make(prefix));
}
private static void lambda$1(String prefix, String s) {
System.out.println(prefix + ":" + s);
}
}
Java 8 lambda expressions
Other typical causes of heap leaks
• Functional expressions in e.g. Scala / Groovy
• Serialization leaks (e.g. Apache Wicket)
• Singletons / enums
• Context frameworks (e.g. DI like Spring)
Stack leaks
HotSpot JVM process
heap perm gen
native
stack
C
sta.
user
managed
string
pool
method
area
pc
reg.
code
cache
young
gen
ten.
gen
const.
pool
e
d
e
n
s
r
.
1
s
r
.
2
class StackLeak {
int SIZE = (int) (0.5 * Runtime
.getRuntime()
.maxMemory());
void foo() {
{
byte[] array1 = new byte[SIZE];
}
byte[] array2 = new byte[SIZE];
}
void bar() {
{
byte[] array1 = new byte[SIZE];
}
byte[] array2 = new byte[10];
byte[] array3 = new byte[SIZE];
}
}
this
void foo() {
{
byte[] array1 = new byte[SIZE];
}
byte[] array2 = new byte[SIZE];
}
array1
SIZEarray1SIZEarray2
localvariablearray
operandstack
this
void bar() {
{
byte[] array1 = new byte[SIZE];
}
byte[] array2 = new byte[1];
byte[] array3 = new byte[SIZE];
}
array1array2
SIZEarray11array2SIZEarray3
array3
localvariablearray
operandstack
“Perm gen“ leaks
HotSpot JVM process
heap perm gen
native
stack
C
sta.
user
managed
string
pool
method
area
pc
reg.
code
cache
young
gen
ten.
gen
const.
pool
e
d
e
n
s
r
.
1
s
r
.
2
new
Foo()
Foo.class
getClass()
ClassLoader()
getClassLoader()
Field field = ClassLoader.class.getDeclaredField("classes");
field.setAccessible(true);
Vector<Class<?>> classes = (Vector<Class<?>>)
field.get(ClassLoader.getSystemClassLoader());
classes
Bar.class
Classes and HotSpot
Foo.klass
MA
Bar.klass
ClassLoaders and HotSpot
null
ClassLoader()
ClassLoader()
ClassLoader() ClassLoader()
bootstrap CL
(bootstrap directory)
extension CL
(extension directory)
system CL
(class path)
user CL
(explicit)
parent
parent
parent
parent
Foo.class
loadClass()
ClassLoader() Thread.class
Foo()Foo.class
Thread()
FooHolder.class
threadLocalMap
class loader leak
ClassLoader()
class FooHolder {
static ThreadLocal<Foo> tlFoo = new ThreadLocal<Foo>();
static { tlFoo.set(new Foo()); }
}
Other typical causes of class loader leaks
• Shut down hooks
• Use of thread context class loaders (e.g. OSGi)
• Service provider interfaces (SPIs)
• JDBC drivers (JDK DriverManager)
• Security frameworks (e.g. JDK Policy)
• Class loader magic (e.g. instrumentation)
Why do modern applications require so much perm gen memory?
class Foo {
public Object bar(Object o) { return o; }
}
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Foo.class);
enhancer.setCallback(new MethodInterceptor() {
@Override public Object intercept(Object obj,
Method method,
Object[] args,
MethodProxy proxy) throws Throwable {
return proxy.invokeSuper(obj, doSomethindWith(args));
}});
Foo enhancedFoo = (Foo) enhancer.create();
Created classes: 2 + #methods * 2
[FastClass, FastMethod, MethodProxy]
Modern JDK‘s inflation works similarly
Method
MethodAccessor
DelegatingMethod-
AccessorImpl
NativeMethod-
AccessorImpl
invoked by
after inflation
(byte code generation)
before inflation
(JNI)
Java 8 meta space
• Permanent generation rebranded (and
probably approximation to JRockit)
• Meta space is allocated in native memory
• No space limit by default (MaxMetaspaceSize)
• Today‘s debugging tools will not be able to
read meta space
Tenuring leaks
HotSpot JVM process
heap perm gen
native
stack
C
sta.
user
managed
string
pool
method
area
pc
reg.
code
cache
young
gen
ten.
gen
const.
pool
e
d
e
n
s
r
.
1
s
r
.
2
public void foo() {
Set<Bar> bars = new HashSet<Bar>();
for(int i = 0; i < 100; i++) {
for(int j = 0; j < 100; j++) {
bars.add(makeBar(i, j));
}
doSomethingWith(bars);
bars.clear();
}
}
public void foo() {
for(int i = 0; i < 100; i++) {
Set<Bar> bars = new HashSet<Bar>();
for(int j = 0; j < 100; j++) {
bars.add(makeBar(i, j));
}
doSomethingWith(bars);
}
}
young generation
Tenured generation
eden survivor 1 survivor 2
bars bars bars bars
collection of survivor 2collection of survivor 1
Implicit memory leaks
• Leaked threads: Require fixed amount of
memory for call stacks / pc register / general
allocation
• Leaked handles (files, sockets, databases):
Usually require JVM memory resources
debugging / profiling
jmap -dump:live,format=b,file=<...> <pid>
java -XX:+HeapDumpOnOutOfMemoryError
-XX:+HeapDumpPath=<...> <...>
jhat <hprof file>
select a from [I a where a.length >= 256
GUI tools: MAT (Eclipse RCP) / JVisualVM / HeapWalker
http://rafael.codes
@rafaelcodes
http://documents4j.com
https://github.com/documents4j/documents4j
http://bytebuddy.net
https://github.com/raphw/byte-buddy

Weitere ähnliche Inhalte

Was ist angesagt?

Designing and Building Next Generation Data Pipelines at Scale with Structure...
Designing and Building Next Generation Data Pipelines at Scale with Structure...Designing and Building Next Generation Data Pipelines at Scale with Structure...
Designing and Building Next Generation Data Pipelines at Scale with Structure...
Databricks
 
ETL With Cassandra Streaming Bulk Loading
ETL With Cassandra Streaming Bulk LoadingETL With Cassandra Streaming Bulk Loading
ETL With Cassandra Streaming Bulk Loading
alex_araujo
 
Get Your Insecure PostgreSQL Passwords to SCRAM
Get Your Insecure PostgreSQL Passwords to SCRAMGet Your Insecure PostgreSQL Passwords to SCRAM
Get Your Insecure PostgreSQL Passwords to SCRAM
Jonathan Katz
 

Was ist angesagt? (20)

MySQL 8.0 EXPLAIN ANALYZE
MySQL 8.0 EXPLAIN ANALYZEMySQL 8.0 EXPLAIN ANALYZE
MySQL 8.0 EXPLAIN ANALYZE
 
Java Performance Analysis on Linux with Flame Graphs
Java Performance Analysis on Linux with Flame GraphsJava Performance Analysis on Linux with Flame Graphs
Java Performance Analysis on Linux with Flame Graphs
 
Microsoft SQL Server Query Tuning
Microsoft SQL Server Query TuningMicrosoft SQL Server Query Tuning
Microsoft SQL Server Query Tuning
 
Understanding Memory Management In Spark For Fun And Profit
Understanding Memory Management In Spark For Fun And ProfitUnderstanding Memory Management In Spark For Fun And Profit
Understanding Memory Management In Spark For Fun And Profit
 
Presto At Arm Treasure Data - 2019 Updates
Presto At Arm Treasure Data - 2019 UpdatesPresto At Arm Treasure Data - 2019 Updates
Presto At Arm Treasure Data - 2019 Updates
 
Kafka 101
Kafka 101Kafka 101
Kafka 101
 
data platform on kubernetes
data platform on kubernetesdata platform on kubernetes
data platform on kubernetes
 
Presto query optimizer: pursuit of performance
Presto query optimizer: pursuit of performancePresto query optimizer: pursuit of performance
Presto query optimizer: pursuit of performance
 
Large partition in Cassandra
Large partition in CassandraLarge partition in Cassandra
Large partition in Cassandra
 
A Rusty introduction to Apache Arrow and how it applies to a time series dat...
A Rusty introduction to Apache Arrow and how it applies to a  time series dat...A Rusty introduction to Apache Arrow and how it applies to a  time series dat...
A Rusty introduction to Apache Arrow and how it applies to a time series dat...
 
Designing and Building Next Generation Data Pipelines at Scale with Structure...
Designing and Building Next Generation Data Pipelines at Scale with Structure...Designing and Building Next Generation Data Pipelines at Scale with Structure...
Designing and Building Next Generation Data Pipelines at Scale with Structure...
 
Elasticsearch in Netflix
Elasticsearch in NetflixElasticsearch in Netflix
Elasticsearch in Netflix
 
Tanel Poder - Scripts and Tools short
Tanel Poder - Scripts and Tools shortTanel Poder - Scripts and Tools short
Tanel Poder - Scripts and Tools short
 
PostgreSQL and JDBC: striving for high performance
PostgreSQL and JDBC: striving for high performancePostgreSQL and JDBC: striving for high performance
PostgreSQL and JDBC: striving for high performance
 
Elasticsearch
ElasticsearchElasticsearch
Elasticsearch
 
Performance Tuning - Memory leaks, Thread deadlocks, JDK tools
Performance Tuning -  Memory leaks, Thread deadlocks, JDK toolsPerformance Tuning -  Memory leaks, Thread deadlocks, JDK tools
Performance Tuning - Memory leaks, Thread deadlocks, JDK tools
 
AWS RDS Benchmark - Instance comparison
AWS RDS Benchmark - Instance comparisonAWS RDS Benchmark - Instance comparison
AWS RDS Benchmark - Instance comparison
 
Secrets of Performance Tuning Java on Kubernetes
Secrets of Performance Tuning Java on KubernetesSecrets of Performance Tuning Java on Kubernetes
Secrets of Performance Tuning Java on Kubernetes
 
ETL With Cassandra Streaming Bulk Loading
ETL With Cassandra Streaming Bulk LoadingETL With Cassandra Streaming Bulk Loading
ETL With Cassandra Streaming Bulk Loading
 
Get Your Insecure PostgreSQL Passwords to SCRAM
Get Your Insecure PostgreSQL Passwords to SCRAMGet Your Insecure PostgreSQL Passwords to SCRAM
Get Your Insecure PostgreSQL Passwords to SCRAM
 

Andere mochten auch

Introduktion till Aspekt-orienterad programmering (AOP) med AspectJ
Introduktion till Aspekt-orienterad programmering (AOP) med AspectJIntroduktion till Aspekt-orienterad programmering (AOP) med AspectJ
Introduktion till Aspekt-orienterad programmering (AOP) med AspectJ
Mattias Jiderhamn
 
第六回渋谷Java Java8のJVM監視を考える
第六回渋谷Java Java8のJVM監視を考える第六回渋谷Java Java8のJVM監視を考える
第六回渋谷Java Java8のJVM監視を考える
chonaso
 

Andere mochten auch (15)

Unsafe Java
Unsafe JavaUnsafe Java
Unsafe Java
 
ClassLoader Leaks
ClassLoader LeaksClassLoader Leaks
ClassLoader Leaks
 
Java 8 Launch - MetaSpaces
Java 8 Launch - MetaSpacesJava 8 Launch - MetaSpaces
Java 8 Launch - MetaSpaces
 
The Java Memory Model
The Java Memory ModelThe Java Memory Model
The Java Memory Model
 
Introduktion till Aspekt-orienterad programmering (AOP) med AspectJ
Introduktion till Aspekt-orienterad programmering (AOP) med AspectJIntroduktion till Aspekt-orienterad programmering (AOP) med AspectJ
Introduktion till Aspekt-orienterad programmering (AOP) med AspectJ
 
mjprof: Monadic approach for JVM profiling
mjprof: Monadic approach for JVM profilingmjprof: Monadic approach for JVM profiling
mjprof: Monadic approach for JVM profiling
 
Coding for Android on steroids with Kotlin
Coding for Android on steroids with KotlinCoding for Android on steroids with Kotlin
Coding for Android on steroids with Kotlin
 
Taking Kotlin to production, Seriously
Taking Kotlin to production, SeriouslyTaking Kotlin to production, Seriously
Taking Kotlin to production, Seriously
 
The Future of Futures - A Talk About Java 8 CompletableFutures
The Future of Futures - A Talk About Java 8 CompletableFuturesThe Future of Futures - A Talk About Java 8 CompletableFutures
The Future of Futures - A Talk About Java 8 CompletableFutures
 
Java GC, Off-heap workshop
Java GC, Off-heap workshopJava GC, Off-heap workshop
Java GC, Off-heap workshop
 
JVM Internals (2015)
JVM Internals (2015)JVM Internals (2015)
JVM Internals (2015)
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
 
Metaspace
MetaspaceMetaspace
Metaspace
 
A look under the hood at Apache Spark's API and engine evolutions
A look under the hood at Apache Spark's API and engine evolutionsA look under the hood at Apache Spark's API and engine evolutions
A look under the hood at Apache Spark's API and engine evolutions
 
第六回渋谷Java Java8のJVM監視を考える
第六回渋谷Java Java8のJVM監視を考える第六回渋谷Java Java8のJVM監視を考える
第六回渋谷Java Java8のJVM監視を考える
 

Ähnlich wie A topology of memory leaks on the JVM

HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
Dmitry Soshnikov
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
Kiyotaka Oku
 
Java Programming Must implement a storage manager that main.pdf
Java Programming Must implement a storage manager that main.pdfJava Programming Must implement a storage manager that main.pdf
Java Programming Must implement a storage manager that main.pdf
adinathassociates
 
Androidの本当にあった怖い話
Androidの本当にあった怖い話Androidの本当にあった怖い話
Androidの本当にあった怖い話
Yusuke Yamamoto
 

Ähnlich wie A topology of memory leaks on the JVM (20)

Java
JavaJava
Java
 
Java 7 Whats New(), Whats Next() from Oredev
Java 7 Whats New(), Whats Next() from OredevJava 7 Whats New(), Whats Next() from Oredev
Java 7 Whats New(), Whats Next() from Oredev
 
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
 
Nantes Jug - Java 7
Nantes Jug - Java 7Nantes Jug - Java 7
Nantes Jug - Java 7
 
Inheritance
InheritanceInheritance
Inheritance
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
 
Java Programming Must implement a storage manager that main.pdf
Java Programming Must implement a storage manager that main.pdfJava Programming Must implement a storage manager that main.pdf
Java Programming Must implement a storage manager that main.pdf
 
Akka Cluster in Java - JCConf 2015
Akka Cluster in Java - JCConf 2015Akka Cluster in Java - JCConf 2015
Akka Cluster in Java - JCConf 2015
 
Testing with Node.js
Testing with Node.jsTesting with Node.js
Testing with Node.js
 
5. Ввод-вывод, доступ к файловой системе
5. Ввод-вывод, доступ к файловой системе5. Ввод-вывод, доступ к файловой системе
5. Ввод-вывод, доступ к файловой системе
 
What`s new in Java 7
What`s new in Java 7What`s new in Java 7
What`s new in Java 7
 
Java7 New Features and Code Examples
Java7 New Features and Code ExamplesJava7 New Features and Code Examples
Java7 New Features and Code Examples
 
Java programming lab_manual_by_rohit_jaiswar
Java programming lab_manual_by_rohit_jaiswarJava programming lab_manual_by_rohit_jaiswar
Java programming lab_manual_by_rohit_jaiswar
 
JNI - Java & C in the same project
JNI - Java & C in the same projectJNI - Java & C in the same project
JNI - Java & C in the same project
 
Nice to meet Kotlin
Nice to meet KotlinNice to meet Kotlin
Nice to meet Kotlin
 
모던자바의 역습
모던자바의 역습모던자바의 역습
모던자바의 역습
 
Androidの本当にあった怖い話
Androidの本当にあった怖い話Androidの本当にあった怖い話
Androidの本当にあった怖い話
 
wtf is in Java/JDK/wtf7?
wtf is in Java/JDK/wtf7?wtf is in Java/JDK/wtf7?
wtf is in Java/JDK/wtf7?
 
Anti patterns
Anti patternsAnti patterns
Anti patterns
 
Multithreading in Java
Multithreading in JavaMultithreading in Java
Multithreading in Java
 

Mehr von Rafael Winterhalter

Mehr von Rafael Winterhalter (16)

Java and OpenJDK: disecting the ecosystem
Java and OpenJDK: disecting the ecosystemJava and OpenJDK: disecting the ecosystem
Java and OpenJDK: disecting the ecosystem
 
The definitive guide to java agents
The definitive guide to java agentsThe definitive guide to java agents
The definitive guide to java agents
 
Byte code field report
Byte code field reportByte code field report
Byte code field report
 
Event-Sourcing Microservices on the JVM
Event-Sourcing Microservices on the JVMEvent-Sourcing Microservices on the JVM
Event-Sourcing Microservices on the JVM
 
Java 10, Java 11 and beyond
Java 10, Java 11 and beyondJava 10, Java 11 and beyond
Java 10, Java 11 and beyond
 
Getting started with Java 9 modules
Getting started with Java 9 modulesGetting started with Java 9 modules
Getting started with Java 9 modules
 
Code generation for alternative languages
Code generation for alternative languagesCode generation for alternative languages
Code generation for alternative languages
 
Monitoring distributed (micro-)services
Monitoring distributed (micro-)servicesMonitoring distributed (micro-)services
Monitoring distributed (micro-)services
 
An Overview of Project Jigsaw
An Overview of Project JigsawAn Overview of Project Jigsaw
An Overview of Project Jigsaw
 
Migrating to JUnit 5
Migrating to JUnit 5Migrating to JUnit 5
Migrating to JUnit 5
 
The Java memory model made easy
The Java memory model made easyThe Java memory model made easy
The Java memory model made easy
 
An introduction to JVM performance
An introduction to JVM performanceAn introduction to JVM performance
An introduction to JVM performance
 
Java byte code in practice
Java byte code in practiceJava byte code in practice
Java byte code in practice
 
Making Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVMMaking Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVM
 
Unit testing concurrent code
Unit testing concurrent codeUnit testing concurrent code
Unit testing concurrent code
 
Understanding Java byte code and the class file format
Understanding Java byte code and the class file formatUnderstanding Java byte code and the class file format
Understanding Java byte code and the class file format
 

Kürzlich hochgeladen

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Kürzlich hochgeladen (20)

Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 

A topology of memory leaks on the JVM

  • 1. A topology of memory leaks on the JVM
  • 2. HotSpot JVM process heap perm gen native stack C sta. user managed string pool method area pc reg. code cache young gen ten. gen const. pool e d e n s r . 1 s r . 2 -Xms -Xmx -Xss -Xsx -XX:PermSize -XX:MaxPermSize (operating system) Java 6 -> 7 Java 7 -> 8
  • 3. genuine leaks HotSpot JVM process heap perm gen native stack C sta. user managed string pool method area pc reg. code cache young gen ten. gen const. pool e d e n s r . 1 s r . 2
  • 4. Field unsafe = Unsafe.class .getDeclaredField("theUnsafe"); unsafe.setAccessible(true); Unsafe theUnsafe = (Unsafe) unsafe.get(null); Allocating native memory with sun.misc.Unsafe 1. Getting hold of “the unsafe“ 2. Allocating native memory final int intSize = 4; long arraySize = (1L + Integer.MAX_VALUE) * intSize; long index = unsafe.allocateMemory(arraySize); Random random = new Random(); for(long l = 0L; l < arraySize; l++) unsafe.putInt(random.nextInt()); 3. (Hopefully) releasing native memory // Without me, the memory leaks unsafe.freeMemory(index);
  • 5. I don‘t do sun.misc.Unsafe 1. But some of your favorite tools do: 1. Kryo (used by e.g. Twitter‘s Storm, Apache Hive) 2. EhCache‘s “big memory“ (used by e.g. Hibernate) 3. JDK (e.g. direct byte buffers) 4. General purpose (e.g. GSON, Snappy) 2. Unsafe to become public API in Java 9 (competition with CLR?) 3. JNI leaks have the same effect 4. Java 8 removes “perm gen“ in favor of native memory “meta space“
  • 6. symptoms of a genuine leak No exception required by JVMS. However, JVM will be untypical slow when: 1. Creating a thread: Requires allocation of new stacks / pc register. 2. Loading a class / JIT: Requires native memory. 3. Doing I/O: Often requires native memory. 4. Calling a native method: Allocates resources on native stack / user space. Swapping can delay execution. 5. Garbage collection: Tenured generation collection needs broad access such that OS must swap back the heap. Rule of thump: All JVM heaps must be swapped back into memory. (Leaked memory will stay swapped out.)
  • 7. Heap leaks HotSpot JVM process heap perm gen native stack C sta. user managed string pool method area pc reg. code cache young gen ten. gen const. pool e d e n s r . 1 s r . 2
  • 8. class FixedSizeStack { private final Object[] objectPool = new Object[10]; private int pointer = -1; public Object pop() { if(pointer < 0) throw new NoSuchElementException(); return objectPool[pointer--]; } public Object peek() { if(pointer < 0) throw new NoSuchElementException(); return objectPool[pointer]; } public void push(Object object) { if(pointer > 8) throw new IllegalStateException("stack overflow"); objectPool[++pointer] = object; } }
  • 9. Element 5 Element 4 Element 3 Element 2 Element 1 Element 0 Stack All memory leaks in Java are linked to reference life cycles.
  • 10. Immutable Stack Element 0 Immutable Stack Element 1 Immutable Stack Element 2
  • 11. public String substring(int beginIndex, int endIndex) { // omitted argument validation return ((beginIndex == 0) && (endIndex == count)) ? this : new String(offset + beginIndex, endIndex - beginIndex, value); } String(int offset, int count, char[] value) { this.value = value; this.offset = offset; this.count = count; } JDK 6
  • 12. XML, anybody? org.xml.sax.DocumentHandler { // several callback methods void characters(char[] ch, int start, int length); } Webpage character blob DocumentHandler few letter word is defined by produces handles
  • 13. public String substring(int beginIndex, int endIndex) { // omitted argument validation int subLen = endIndex - beginIndex; return ((beginIndex == 0) && (endIndex == value.length)) ? this : new String(value, beginIndex, subLen); } public String(char[] value, int offset, int count) { // omitted argument validation this.value = Arrays.copyOfRange(value, offset, offset + count); } JDK 7
  • 14. interface Message extends Serializable { String getInfo(); } class ExampleActivity extends Activity { @Override public void onCreate(Bundle bundle) { startService( new Intent(this, getClass()) .putExtra( "foo", new Message() { @Override public String getInfo() { return "bar"; } })); } } A classic Android leak
  • 15. class ExampleActivity$1 implements Message { private ExampleActivity this$0; ExampleActivity$1(ExampleActivity this$0) { this.this$0 = this$0; } @Override public String getInfo() { return "bar"; } } new Message() { @Override public String getInfo() { return "bar"; } } uncompiled desugared Non-static inner classes
  • 16. class Foo { void bar() { List<String> list = Arrays.asList("foo", "bar"); list.forEach(LambdaMetafactory .INVOKEDYNAMIC(Foo::lambda$1) .make()); } private static void lambda$1(String s) { System.out.println(s); } } class Foo { void bar() { List<String> list = Arrays.asList("foo", "bar"); list.forEach(s -> { System.out.println(s); }); } } uncompiled desugared Java 8 lambda expressions
  • 17. class Foo { final String prefix; // constructor omitted void bar() { List<String> list = Arrays.asList("foo", "bar"); list.forEach(s -> { System.out.println( prefix + ":" + s) }); } } uncompiled desugared Java 8 lambda expressions class Foo { final String prefix; // constructor omitted void bar() { List<String> list = Arrays.asList("foo", "bar"); list.forEach(LambdaMetaFactory .INVOKEDYNAMIC(this::lambda$1) .make()); } private void lambda$1(String s) { System.out.println(this.prefix + ":" + s); } }
  • 18. uncompiled desugared class Foo { final String prefix; // constructor omitted void bar() { List<String> list = Arrays.asList("foo", "bar"); String prefix = this.prefix; list.forEach(s -> { System.out.println( prefix + ":" + s)}); } } class Foo { final String prefix; // constructor omitted void bar() { List<String> list = Arrays.asList("foo", "bar"); String prefix = this.prefix; list.forEach(LambdaMetafactory .INVOKEDYNAMIC(Foo::lambda$1) .make(prefix)); } private static void lambda$1(String prefix, String s) { System.out.println(prefix + ":" + s); } } Java 8 lambda expressions
  • 19. Other typical causes of heap leaks • Functional expressions in e.g. Scala / Groovy • Serialization leaks (e.g. Apache Wicket) • Singletons / enums • Context frameworks (e.g. DI like Spring)
  • 20. Stack leaks HotSpot JVM process heap perm gen native stack C sta. user managed string pool method area pc reg. code cache young gen ten. gen const. pool e d e n s r . 1 s r . 2
  • 21. class StackLeak { int SIZE = (int) (0.5 * Runtime .getRuntime() .maxMemory()); void foo() { { byte[] array1 = new byte[SIZE]; } byte[] array2 = new byte[SIZE]; } void bar() { { byte[] array1 = new byte[SIZE]; } byte[] array2 = new byte[10]; byte[] array3 = new byte[SIZE]; } }
  • 22. this void foo() { { byte[] array1 = new byte[SIZE]; } byte[] array2 = new byte[SIZE]; } array1 SIZEarray1SIZEarray2 localvariablearray operandstack
  • 23. this void bar() { { byte[] array1 = new byte[SIZE]; } byte[] array2 = new byte[1]; byte[] array3 = new byte[SIZE]; } array1array2 SIZEarray11array2SIZEarray3 array3 localvariablearray operandstack
  • 24. “Perm gen“ leaks HotSpot JVM process heap perm gen native stack C sta. user managed string pool method area pc reg. code cache young gen ten. gen const. pool e d e n s r . 1 s r . 2
  • 25. new Foo() Foo.class getClass() ClassLoader() getClassLoader() Field field = ClassLoader.class.getDeclaredField("classes"); field.setAccessible(true); Vector<Class<?>> classes = (Vector<Class<?>>) field.get(ClassLoader.getSystemClassLoader()); classes Bar.class Classes and HotSpot Foo.klass MA Bar.klass
  • 26. ClassLoaders and HotSpot null ClassLoader() ClassLoader() ClassLoader() ClassLoader() bootstrap CL (bootstrap directory) extension CL (extension directory) system CL (class path) user CL (explicit) parent parent parent parent Foo.class loadClass()
  • 27. ClassLoader() Thread.class Foo()Foo.class Thread() FooHolder.class threadLocalMap class loader leak ClassLoader() class FooHolder { static ThreadLocal<Foo> tlFoo = new ThreadLocal<Foo>(); static { tlFoo.set(new Foo()); } }
  • 28. Other typical causes of class loader leaks • Shut down hooks • Use of thread context class loaders (e.g. OSGi) • Service provider interfaces (SPIs) • JDBC drivers (JDK DriverManager) • Security frameworks (e.g. JDK Policy) • Class loader magic (e.g. instrumentation)
  • 29. Why do modern applications require so much perm gen memory? class Foo { public Object bar(Object o) { return o; } } Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Foo.class); enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { return proxy.invokeSuper(obj, doSomethindWith(args)); }}); Foo enhancedFoo = (Foo) enhancer.create(); Created classes: 2 + #methods * 2 [FastClass, FastMethod, MethodProxy]
  • 30. Modern JDK‘s inflation works similarly Method MethodAccessor DelegatingMethod- AccessorImpl NativeMethod- AccessorImpl invoked by after inflation (byte code generation) before inflation (JNI)
  • 31. Java 8 meta space • Permanent generation rebranded (and probably approximation to JRockit) • Meta space is allocated in native memory • No space limit by default (MaxMetaspaceSize) • Today‘s debugging tools will not be able to read meta space
  • 32. Tenuring leaks HotSpot JVM process heap perm gen native stack C sta. user managed string pool method area pc reg. code cache young gen ten. gen const. pool e d e n s r . 1 s r . 2
  • 33. public void foo() { Set<Bar> bars = new HashSet<Bar>(); for(int i = 0; i < 100; i++) { for(int j = 0; j < 100; j++) { bars.add(makeBar(i, j)); } doSomethingWith(bars); bars.clear(); } } public void foo() { for(int i = 0; i < 100; i++) { Set<Bar> bars = new HashSet<Bar>(); for(int j = 0; j < 100; j++) { bars.add(makeBar(i, j)); } doSomethingWith(bars); } } young generation Tenured generation eden survivor 1 survivor 2 bars bars bars bars collection of survivor 2collection of survivor 1
  • 34. Implicit memory leaks • Leaked threads: Require fixed amount of memory for call stacks / pc register / general allocation • Leaked handles (files, sockets, databases): Usually require JVM memory resources
  • 35. debugging / profiling jmap -dump:live,format=b,file=<...> <pid> java -XX:+HeapDumpOnOutOfMemoryError -XX:+HeapDumpPath=<...> <...> jhat <hprof file> select a from [I a where a.length >= 256 GUI tools: MAT (Eclipse RCP) / JVisualVM / HeapWalker