Java Memr PDF
Java Memr PDF
Märt Bakhoff
Java Fundamentals
01.11.2016
Agenda
●
JVM memory
●
Reference objects
●
Monitoring
●
Garbage collectors
– ParallelGC
– G1GC
2/144
JVM memory
●
Heap (user objects)
●
Non-heap
– Stack (per thread: call stack, local variables)
– Metaspace (class metadata)
– Direct Byte Buffers
– Native stuff (JNI, Java internals)
3/144
Method call Locals Address Value
5/144
PermGen
●
Java 8+: class metadata lives in Metaspace
●
-XX:MaxMetaspaceSize=size (default: unlimited)
●
Older versions: classes live in PermGen,
PermGen is a special part of the heap
●
OutOfMemoryError: PermGen space
●
-XX:MaxPermSize=size (default: limited)
6/144
Generating garbage
●
Primitives in the stack, objects in the heap
●
Using new allocates objects in the heap
●
When and how are objects “deleted” and
heap space freed up?
7/144
Garbage collection (GC)
●
Sort garbage / live objects
●
Reclaims heap space
●
Fully automatic, no manual deallocation
Java GC vs C++ new/delete
●
Different GC algorithms exist
8/144
GC advantages
●
Avoid bugs
– forgetting to free the memory
– double freeing memory
– using already freed memory
●
Java specific
– No direct memory access
– Can't accidentally overwrite unrelated memory
9/144
GC disadvantages
●
Consumes resources
●
Automatic, no manual control
●
Unpredictable stalls
●
Harder to understand
10/144
How does it work?
●
Basic principle
– Find referenced objects
– Everything else is garbage
●
Reachability (GC roots)
– Classes loaded by system classloader (static fields!)
– Stack locals (local variables, parameters)
– Active threads
– JNI References
11/144
Consumes resources?
●
Extra memory + CPU for bookkeeping
●
Stop The World pauses all threads
●
Some applications need to tune GC:
pause duration vs pause frequency
12/144
Generational GC
●
Most objects die young
●
Generations: memory pools holding objects
of different ages
– Young generation: eden, survivors
– Old/tenured generation
●
Young-Old default size ratio 1:2
13/144
Young/Old
YOUNG GEN
(frequent collections)
14/144
GC algoritms
●
Serial
●
Parallel
●
Concurrent Mark-Sweep
●
Garbage first (G1)
●
IBM, Azul special stuff
15/144
Agenda
●
JVM memory
●
Reference objects
●
Monitoring
●
Garbage collectors
– ParallelGC
– G1GC
16/144
Reference objects
●
java.lang.ref package docs are useful
●
WeakReference<T>
●
PhantomReference<T>
●
ReferenceQueue<T>
17/144
Detour: memory leaks
interface Passenger {
void trainArrived();
}
class TrainStation {
private final List<Passenger> passengers = new...
public void startWaiting(Passenger passenger) {
passengers.add(passenger);
}
public void leave(Passenger passenger) {
passengers.remove(passenger);
}
public void onTrainArrived() {
passengers.forEach(Passenger::trainArrived);
}
}
18/144
Detour: memory leaks
interface Passenger {
void trainArrived();
}
class TrainStation {
private final List<Passenger> passengers = new...
public void startWaiting(Passenger passenger) {
passengers.add(passenger);
}
public void leave(Passenger passenger) {
passengers.remove(passenger);
}
public void onTrainArrived() {
passengers.forEach(Passenger::trainArrived);
}
}
19/144
WeakReference<T>
Keep a reference without preventing GC
class TrainStation {
private final List<Passenger> passengers = new...
public void startWaiting(Passenger passenger) {
passengers.add(passenger);
}
public void leave(Passenger passenger) {
passengers.remove(passenger);
}
public void onTrainArrived() {
passengers.forEach(Passenger::trainArrived);
}
}
21/144
Weaker TrainStation
class TrainStation {
private List<WeakReference<Passenger>> passengers;
23/144
Detour: finalizers
From “Effective Java” by Joshua Bloch
●
Finalizers are unpredictable, often
dangerous, and generally unnecessary.
●
Not only does the language specification
provide no guarantee that finalizers will get
executed promptly; it provides no guarantee
that they’ll get executed at all.
24/144
Detour: finalizers
Trolling the garbage collector:
public class Test {
static Test t;
@Override
public void finalize() {
t = this; // I refuse to die
}
}
25/144
PhantomReference<T>
●
Not a reference, but a GC token
●
Only usable with a ReferenceQueue
●
Enqueued by the garbage collector,
only after referent is collected
●
get() -> null always!
26/144
PhantomReference<T>
Example e = new Example();
ReferenceQueue<Example> queue =
new ReferenceQueue<>();
PhantomReference<Example> phantom =
new PhantomReference<>(e, queue);
e = null;
28/144
GC logging
●
-XX:+PrintGCTimeStamps
●
-XX:+PrintGCDetails
●
-Xloggc:filename
●
Output depends heavily on GC algo
●
Read the fine manual:
plumbr.eu/java-garbage-collection-handbook
“GC Algorithms: Implementations”
29/144
ParallelGC minor
2015-05-26T14:27:40.915-0200: 116.115:
[GC (Allocation Failure)
[PSYoungGen: 2 694 440K -> 1 305 132K (2 796 544K)]
9 556 775K -> 8 438 926K (11 185 152K), 0.24066 secs
]
[Times: user=1.77 sys=0.01, real=0.24 secs]
30/144
ParallelGC full
2015-05-26T14:27:41.155-0200: 116.356:
[Full GC (Ergonomics)
[PSYoungGen: 1 305 132K -> 0K(2 796 544K)]
[ParOldGen: 7 133 794K -> 6 597 672K (8 388 608K)]
8 438 926K -> 6 597 672K (11 185 152K),
[Metaspace: 6 745K -> 6 745K (1 056 768K)] ,
0.91588 secs
]
[Times: user=4.49 sys=0.64, real=0.92 secs]
31/144
G1 minor
0.134: [GC pause (G1 Evacuation Pause)
(young), 0.0144119 secs] ... [
Eden: 24.0M (24.0M) -> 0.0B (13.0M)
Survivors: 0.0B -> 3072.0K
Heap: 24.0M (256.0M) -> 21.9M (256.0M)
]
[Times: user=0.04 sys=0.04, real=0.02 secs]
32/144
GC overhead
116.356: [Full GC ...
117.331: [Full GC ...
118.378: [Full GC ...
119.316: [Full GC ...
java.lang.OutOfMemoryError:
GC overhead limit exceeded
Frequent+quick minor collections expected
33/144
Heap dumps
●
JVisualVM
●
Eclipse memory analyzer (MAT)
●
jmap -heap / -histo / -dump:... <pid>
●
-XX:+HeapDumpOnOutOfMemory
-XX:HeapDumpPath=path
34/144
jmap
$ jmap -heap 1244
Heap Usage: PS Old Generation
36/144
jps + jmap
$ jps -lv
30086 com.intellij.idea.Main ...
1738 sun.tools.jps.Jps ...
1659 org.jetbrains.jps.cmdline.Launcher ...
1660 com.intellij.rt.execution.application.AppMain ...
$ jmap -dump:format=b,file=dump.bin 1660
Dumping heap to /tmp/dump.bin ...
Heap dump file created
37/144
Eclipse memory analyzer
38/144
Eclipse memory analyzer
39/144
JVisualVM
40/144
JVisualVM
41/144
JVisualVM
●
Bundled with JDK
●
Windows:
C:\Program Files\Java\jdk1.8.x\bin\jvisualvm.exe
●
Linux:
jvisualvm or visualvm
(apt-get install visualvm)
●
Compile & Run: https://goo.gl/L3dhos
42/144
5min break
43/144
Agenda
●
JVM memory
●
Reference objects
●
Monitoring
●
Garbage collectors
– ParallelGC
– G1GC
44/144
ParallelGC
●
GC roots
– static fields
– stack locals
– threads
●
Young gen: eden, survivor to/from
●
Old gen
●
Stop The World pauses
45/144
RUNNING/
GC ROOTS STACK STATIC FIELDS
STOP THE WORLD
YOUNG
46/144
RUNNING
GC ROOTS STACK STATIC FIELDS
EDEN S1 S2 OLD
47/144
RUNNING
GC ROOTS STACK STATIC FIELDS
EDEN S1 S2 OLD
48/144
RUNNING
GC ROOTS STACK STATIC FIELDS
EDEN S1 S2 OLD
49/144
RUNNING
GC ROOTS STACK STATIC FIELDS
EDEN S1 S2 OLD
50/144
RUNNING
GC ROOTS STACK STATIC FIELDS
EDEN S1 S2 OLD
51/144
RUNNING
GC ROOTS STACK STATIC FIELDS
EDEN S1 S2 OLD
52/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
EDEN S1 S2 OLD
2015-05-26T14:27:40.915-0200: 116.115:
[GC (Allocation Failure) ... ]
53/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
EDEN S1 S2 OLD
54/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
EDEN S1 S2 OLD
55/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
EDEN S1 S2 OLD
56/144
RUNNING
GC ROOTS STACK STATIC FIELDS
1 1
EDEN S1 S2 OLD
57/144
RUNNING
GC ROOTS STACK STATIC FIELDS
1 1
EDEN S1 S2 OLD
58/144
RUNNING
GC ROOTS STACK STATIC FIELDS
1 1
EDEN S1 S2 OLD
59/144
RUNNING
GC ROOTS STACK STATIC FIELDS
1 1
EDEN S1 S2 OLD
60/144
RUNNING
GC ROOTS STACK STATIC FIELDS
1 1
EDEN S1 S2 OLD
61/144
RUNNING
GC ROOTS STACK STATIC FIELDS
1 1
EDEN S1 S2 OLD
62/144
RUNNING
GC ROOTS STACK STATIC FIELDS
1 1
EDEN S1 S2 OLD
63/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
1 1
EDEN S1 S2 OLD
2015-05-26T14:27:41.915-0200: 117.115:
[GC (Allocation Failure) ... ]
64/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
1 1
EDEN S1 S2 OLD
65/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
1 1
EDEN S1 S2 OLD
66/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
1 1
EDEN S1 S2 OLD
67/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
1
EDEN S1 S2 OLD
68/144
RUNNING
GC ROOTS STACK STATIC FIELDS
2 1 1
EDEN S1 S2 OLD
69/144
RUNNING
GC ROOTS STACK STATIC FIELDS
2 1 1
EDEN S1 S2 OLD
70/144
RUNNING
GC ROOTS STACK STATIC FIELDS
2 1 1
EDEN S1 S2 OLD
71/144
RUNNING
GC ROOTS STACK STATIC FIELDS
2 1 1
EDEN S1 S2 OLD
72/144
RUNNING
GC ROOTS STACK STATIC FIELDS
2 1 1
EDEN S1 S2 OLD
73/144
RUNNING
GC ROOTS STACK STATIC FIELDS
2 1 1
EDEN S1 S2 OLD
74/144
RUNNING
GC ROOTS STACK STATIC FIELDS
2 1 1
EDEN S1 S2 OLD
75/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
2 1 1
EDEN S1 S2 OLD
2015-05-26T14:27:43.915-0200: 119.115:
[GC (Allocation Failure) ... ]
76/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
2 1 1
EDEN S1 S2 OLD
77/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
2 1 1
EDEN S1 S2 OLD
78/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
1 1 2
EDEN S1 S2 OLD
79/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
1 1 2
EDEN S1 S2 OLD
80/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
1 1 2
EDEN S1 S2 OLD
Card Table
81/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
1 1 2
EDEN S1 S2 OLD
Card Table
82/144
RUNNING
GC ROOTS STACK STATIC FIELDS
2 2 1
EDEN S1 S2 OLD
Card Table
83/144
RUNNING
GC ROOTS STACK STATIC FIELDS
2 2 1
EDEN S1 S2 OLD
Card Table
84/144
RUNNING
GC ROOTS STACK STATIC FIELDS
2 2 1
EDEN S1 S2 OLD
Card Table
85/144
RUNNING
GC ROOTS STACK STATIC FIELDS
2 2 1
EDEN S1 S2 OLD
Card Table
86/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
2 2 1
EDEN S1 S2 OLD
Card Table
2015-05-26T14:27:44.915-0200: 120.115:
[GC (Allocation Failure) ... ]
87/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
2 2 1
EDEN S1 S2 OLD
Card Table
88/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
2 2 1
EDEN S1 S2 OLD
Card Table
89/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
2 2 1
EDEN S1 S2 OLD
Card Table
90/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
2 2 1
EDEN S1 S2 OLD
Card Table
91/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
2 1 2
EDEN S1 S2 OLD
Card Table
92/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
2 1 2
EDEN S1 S2 OLD
Card Table
93/144
STOP THE WORLD
GC ROOTS STACK STATIC FIELDS
1 2
EDEN S1 S2 OLD
Card Table
94/144
RUNNING
GC ROOTS STACK STATIC FIELDS
2 1 1 1
EDEN S1 S2 OLD
Card Table
95/144
Recap: ParallelGC
●
Allocate to eden
●
Copy live objects to survivors or old
●
Clear entire eden + cleared survivor space
●
Promote repeat-survivors to Old gen
●
Use Card Tables to avoid scanning Old gen
●
Use Old objects as GC roots in minor collection
●
Full GC when everything is full
96/144
ParallelGC insights (1)
●
Reference scanning expensive
●
size(Old) > size(Young)
●
Card Table -> avoid most scanning
2 2 1
EDEN S1 S2 OLD
Card Table
97/144
ParallelGC insights (2)
●
Objects die young
●
Copy only live objects
●
Don’t touch Old Gen until Full GC
98/144
G1
●
Generational: young (eden, survivor), old
●
Aims for short Stop The World pauses
●
Thousands of non-contiguous regions
●
Concurrent marking
99/144
RUNNING/
STOP THE WORLD
GC ROOTS
STACK
STATIC FIELDS
FREE
EDEN
SURVIVOR
OLD
100/144
RUNNING
GC ROOTS
STACK
STATIC FIELDS
FREE
EDEN
SURVIVOR
OLD
101/144
RUNNING
GC ROOTS
STACK
STATIC FIELDS
FREE
EDEN
SURVIVOR
OLD
102/144
RUNNING
GC ROOTS
STACK
STATIC FIELDS
FREE
EDEN
SURVIVOR
OLD
103/144
RUNNING
GC ROOTS
STACK
STATIC FIELDS
FREE
EDEN
SURVIVOR
OLD
104/144
RUNNING
GC ROOTS
STACK
STATIC FIELDS
FREE
EDEN
SURVIVOR
OLD
105/144
STOP THE WORLD
GC ROOTS
STACK
STATIC FIELDS
FREE
EDEN
SURVIVOR
OLD
GC ROOTS
STACK
STATIC FIELDS
FREE
EDEN
SURVIVOR
OLD
GC ROOTS
STACK
STATIC FIELDS
FREE
EDEN
SURVIVOR
OLD
108/144
STOP THE WORLD
GC ROOTS
STACK
STATIC FIELDS
FREE
EDEN
SURVIVOR
OLD
GC ROOTS
STACK
STATIC FIELDS
FREE
EDEN
SURVIVOR
OLD
GC ROOTS
STACK
STATIC FIELDS
1
1
FREE
EDEN
SURVIVOR
OLD
111/144
RUNNING
GC ROOTS
STACK
STATIC FIELDS
1
1
FREE
EDEN
SURVIVOR
OLD
112/144
RUNNING
GC ROOTS
STACK
STATIC FIELDS
1
1
FREE
EDEN
SURVIVOR
OLD
113/144
RUNNING
GC ROOTS
STACK
STATIC FIELDS
1
1
FREE
EDEN
SURVIVOR
OLD
114/144
RUNNING
GC ROOTS
STACK
STATIC FIELDS
1
1
FREE
EDEN
SURVIVOR
OLD
115/144
STOP THE WORLD
GC ROOTS
STACK
STATIC FIELDS
1
1
FREE
EDEN
SURVIVOR
OLD
GC ROOTS
STACK
STATIC FIELDS
1
1
FREE
EDEN
SURVIVOR
OLD
GC ROOTS
STACK
STATIC FIELDS
1
1
FREE
EDEN
SURVIVOR
OLD
GC ROOTS
STACK
STATIC FIELDS
1
FREE
EDEN
SURVIVOR
1
OLD
GC ROOTS
STACK
STATIC FIELDS
1
FREE
EDEN
SURVIVOR
1
OLD
GC ROOTS
STACK
STATIC FIELDS
FREE
EDEN
SURVIVOR
1
OLD
GC ROOTS
STACK
STATIC FIELDS
FREE
EDEN
SURVIVOR
1
OLD
GC ROOTS
STACK
STATIC FIELDS 1 1
1
FREE
EDEN
SURVIVOR
OLD
123/144
RUNNING
GC ROOTS
STACK
STATIC FIELDS 1 1
1
FREE
EDEN
SURVIVOR
OLD
124/144
RUNNING
GC ROOTS
STACK
STATIC FIELDS 1 1
1
FREE
EDEN
SURVIVOR
OLD
125/144
RUNNING
GC ROOTS
STACK
STATIC FIELDS 1 1
1
FREE
EDEN
SURVIVOR
OLD
GC ROOTS
STACK
STATIC FIELDS 1 1
1
FREE
EDEN
SURVIVOR
OLD
127/144
STOP THE WORLD
GC ROOTS
STACK
STATIC FIELDS 1 1
1
FREE
EDEN
SURVIVOR
OLD
GC ROOTS
STACK
STATIC FIELDS 1 1
1
FREE
EDEN
SURVIVOR
OLD
GC ROOTS
STACK
STATIC FIELDS 1 1
1
FREE
EDEN
SURVIVOR
OLD
GC ROOTS
STACK
STATIC FIELDS 1 1
1
FREE
EDEN
SURVIVOR
OLD
GC ROOTS
STACK
STATIC FIELDS 1
1
FREE
EDEN
SURVIVOR
OLD
1
GC ROOTS
STACK
STATIC FIELDS 1
1
FREE
EDEN
SURVIVOR
OLD
1
GC ROOTS
STACK
STATIC FIELDS 1
1
FREE
EDEN
SURVIVOR
OLD
1
GC ROOTS
STACK
STATIC FIELDS
FREE
EDEN
SURVIVOR
OLD
1
GC ROOTS
STACK
STATIC FIELDS 1
1
FREE
EDEN
SURVIVOR
OLD
136/144
Meanwhile..
●
Concurrent marking
●
Start from GC roots
●
Find all live objects
●
Sort regions by “liveness”
137/144
After concurrent marking
●
Stop The World
●
Scrub RSets
●
Collection set: all young
+ Old with least live objects
●
1.269: [GC pause (mixed) ... ]
●
Amount of old regions selected ~ pause time
138/144
Recap: G1
●
Use concurrent marking
●
Collection set: all young
+ hand picked old (most garbage)
●
Find live objects from GC roots + RSets
●
Compact to new survivors / old regions
●
Free entire evacuated regions
139/144
G1 insights
●
Avoid reference scanning with RSets
●
Avoid long pauses with mixed collection:
never clean entire Old Gen
●
Only collect Old regions with most garbage
– -> don’t touch live Old objects
– -> more time to become garbage
– Less live objects -> less copying
140/144
Homework (1)
●
Use PhantomReferences to write a finalize() replacement
●
User can register several cleanup tasks for any object
●
PostCollectionTaskRunner starts a thread that runs
cleanup tasks in the background
interface PostCollectionTaskRunner {
void register(Object o, Runnable task);
void shutdown() throws Exception;
}
141/144
Homework (2)
●
Run with ParallelGC (Java8 default).
Enable detailed GC logging. Cause a Full GC.
●
Submit the GC log + following comments:
– for one minor collection: time since last collection and bytes
freed for young gen
– for one Full GC: bytes freed for young gen, old gen, total heap
size
●
Use max heap size 64M
●
Also submit code for triggering Full GC
142/144
Homework (3)
●
Phantoms expensive ->
use 1 per managed object
●
Don’t keep stuff for dead objects
●
Reasonably efficient code:
no Thread#sleep, crazy list iterations, etc.
●
shutdown() -> stop thread, clear data
●
Deadline: 07 Nov 23:59 local time
143/144
Read more..
●
https://docs.oracle.com/javase/8/docs/technotes/guid
es/vm/gctuning/
●
https://plumbr.eu/handbook/garbage-collection-
algorithms-implementations
●
https://vimeo.com/181948157
●
https://stackoverflow.com/q/19154607
●
http://insightfullogic.com/2013/Mar/06/garbage-
collection-java-2/
144/144