SlideShare uma empresa Scribd logo
1 de 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

Mais conteúdo relacionado

Mais procurados

Mais procurados (20)

Building an Activity Feed with Cassandra
Building an Activity Feed with CassandraBuilding an Activity Feed with Cassandra
Building an Activity Feed with Cassandra
 
Rust と Wasmの現実
Rust と Wasmの現実Rust と Wasmの現実
Rust と Wasmの現実
 
Introducing the TPCx-HS Benchmark for Big Data
Introducing the TPCx-HS Benchmark for Big DataIntroducing the TPCx-HS Benchmark for Big Data
Introducing the TPCx-HS Benchmark for Big Data
 
Optimizing Kubernetes Resource Requests/Limits for Cost-Efficiency and Latenc...
Optimizing Kubernetes Resource Requests/Limits for Cost-Efficiency and Latenc...Optimizing Kubernetes Resource Requests/Limits for Cost-Efficiency and Latenc...
Optimizing Kubernetes Resource Requests/Limits for Cost-Efficiency and Latenc...
 
Spark Summit EU talk by Ted Malaska
Spark Summit EU talk by Ted MalaskaSpark Summit EU talk by Ted Malaska
Spark Summit EU talk by Ted Malaska
 
Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021
Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021
Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021
 
Apache Spark Architecture
Apache Spark ArchitectureApache Spark Architecture
Apache Spark Architecture
 
Getting The Best Performance With PySpark
Getting The Best Performance With PySparkGetting The Best Performance With PySpark
Getting The Best Performance With PySpark
 
はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)
 
Top 5 Mistakes to Avoid When Writing Apache Spark Applications
Top 5 Mistakes to Avoid When Writing Apache Spark ApplicationsTop 5 Mistakes to Avoid When Writing Apache Spark Applications
Top 5 Mistakes to Avoid When Writing Apache Spark Applications
 
Javaトラブルに備えよう #jjug_ccc #ccc_h2
Javaトラブルに備えよう #jjug_ccc #ccc_h2Javaトラブルに備えよう #jjug_ccc #ccc_h2
Javaトラブルに備えよう #jjug_ccc #ccc_h2
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
 
A whirlwind tour of the LLVM optimizer
A whirlwind tour of the LLVM optimizerA whirlwind tour of the LLVM optimizer
A whirlwind tour of the LLVM optimizer
 
Apache Sparkにおけるメモリ - アプリケーションを落とさないメモリ設計手法 -
Apache Sparkにおけるメモリ - アプリケーションを落とさないメモリ設計手法 -Apache Sparkにおけるメモリ - アプリケーションを落とさないメモリ設計手法 -
Apache Sparkにおけるメモリ - アプリケーションを落とさないメモリ設計手法 -
 
Introducing envoy-based service mesh at Booking.com
Introducing envoy-based service mesh at Booking.comIntroducing envoy-based service mesh at Booking.com
Introducing envoy-based service mesh at Booking.com
 
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
 
Data Source API in Spark
Data Source API in SparkData Source API in Spark
Data Source API in Spark
 
Common issues with Apache Kafka® Producer
Common issues with Apache Kafka® ProducerCommon issues with Apache Kafka® Producer
Common issues with Apache Kafka® Producer
 
Play2 scalaを2年やって学んだこと
Play2 scalaを2年やって学んだことPlay2 scalaを2年やって学んだこと
Play2 scalaを2年やって学んだこと
 
Morel, a Functional Query Language
Morel, a Functional Query LanguageMorel, a Functional Query Language
Morel, a Functional Query Language
 

Destaque

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
 

Destaque (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監視を考える
 

Semelhante a 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
 

Semelhante a 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
 

Mais de Rafael Winterhalter

Mais de 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
 

Último

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
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
 

Último (20)

Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
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
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
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...
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 

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