“Just leave the garbage outside and we will take care of it for you”. This is the panacea promised by garbage collection mechanisms built into most software stacks available today. So, we don’t need to think about it anymore, right? Wrong! When misused, garbage collectors can fail miserably. When this happens they slow down your application and lead to unacceptable pauses. In this talk we will go over different garbage collectors approaches and understand under which conditions they function well.
20. NEXT
Concurrency - Every change to reference requires a memory barrier
Very bad for highly concurrent systems Mostly relevant for single threaded
20
Reference Counting Concurrency
38. NEXT
Sweep through the heap and collect all unmarked objects
Maintain a list of free memory portions
Work: O(#Objects and
fragments in Heap)
Heap
Unreachable
Reachable
Free
38
Mark & Sweep : Sweep
57. NEXT
57
The Open JDK GCs - Serial
Property Serial
-XX:+UseSerialGC
Compacting
Regional
Generational
Concurrent
Mostly Concurrent
When To Use Small Heaps
Single cpu
containers
(*) can be found as part of Corretto JDK
58. NEXT
58
The Open JDK GCs - Parallel
Property Serial
-XX:+UseSerialGC
Parallel
-XX:+UseParallelGC
Compacting
Regional
Generational
Concurrent
Mostly Concurrent
When To Use Small Heaps
Single cpu
containers
High throughput
Latency of a
single response is
not important
(*) can be found as part of Corretto JDK
59. NEXT
59
The Open JDK GCs - G1GC
Property Serial
-XX:+UseSerialGC
Parallel
-XX:+UseParallelGC
G1
-XX:+UseG1GC
Compacting
Regional
Generational
Concurrent <200ms
Mostly Concurrent Old gen only
When To Use Small Heaps
Single cpu
containers
High throughput
Latency of a
single response is
not important
Mainstream
applications
(*) can be found as part of Corretto JDK
60. NEXT
60
The Open JDK GCs - ZGC
Property Serial
-XX:+UseSerialGC
Parallel
-XX:+UseParallelGC
G1
-XX:+UseG1GC
ZGC
-XX:+UseG1GC
Compacting
Regional
Generational WIP
Concurrent <200ms <1ms
Mostly Concurrent Old gen only
When To Use Small Heaps
Single cpu
containers
High throughput
Latency of a
single response is
not important
Mainstream
applications
Large Heaps
Highly
responsive
(*) can be found as part of Corretto JDK
61. NEXT
61
The Open JDK GCs - Shenandoah
Property Serial
-XX:+UseSerialGC
Parallel
-XX:+UseParallelGC
G1
-XX:+UseG1GC
ZGC
-XX:+UseG1GC
Shenandoah(*)
-XX:+UseShenandoahGC
Compacting
Regional
Generational WIP WIP
Concurrent <200ms <1ms <1ms
Mostly Concurrent Old gen only
When To Use Small Heaps
Single cpu
containers
High throughput
Latency of a
single response is
not important
Mainstream
applications
Large Heaps
Highly
responsive
Large Heaps
Highly responsive
(*) can be found as part of Corretto JDK
67. NEXT
67
GC Logs
[2022-09-01T17:30:40.433+0000][0.004s][info][gc] Using G1
[2022-09-01T17:30:41.975+0000][1.546s][info][gc] GC(0) Pause Young (Concurrent Start) (Metadata GC
Threshold) 126M->30M(4096M) 12.598ms
[2022-09-01T17:30:41.975+0000][1.546s][info][gc] GC(1) Concurrent Mark Cycle
[2022-09-01T17:30:41.988+0000][1.558s][info][gc] GC(1) Pause Remark 32M->22M(4096M) 2.119ms
[2022-09-01T17:30:41.988+0000][1.558s][info][gc] GC(1) Pause Cleanup 22M->22M(4096M) 0.003ms
[2022-09-01T17:30:42.052+0000][1.622s][info][gc] GC(1) Concurrent Mark Cycle 76.584ms
[2022-09-01T17:30:42.824+0000][2.395s][info][gc] GC(2) Pause Young (Concurrent Start) (Metadata GC
68. NEXT
68
GC Logs - Description
[2022-09-01T17:32:31.262+0000][110.832s][info][gc] GC(15) Pause Young (Normal) (G1 Evacuation Pause)
486M->130M(4096M) 93.914ms
69. NEXT
69
GC Logs - Time Stamp (when)
[2022-09-01T17:32:31.262+0000][110.832s]
[info][gc] GC(15) Pause Young (Normal) (G1 Evacuation Pause)
486M->130M(4096M) 93.914ms
70. NEXT
70
GC Logs - Memory released (how much)
[2022-09-01T17:32:31.262+0000][110.832s]
[info][gc] GC(15) Pause Young (Normal) (G1 Evacuation Pause)
486M->130M(4096M) 93.914ms
71. NEXT
71
GC Logs - Memory released (how long )
[2022-09-01T17:32:31.262+0000][110.832s]
[info][gc] GC(15) Pause Young (Normal) (G1 Evacuation Pause)
486M->130M(4096M) 93.914ms
72. NEXT
72
GC Logs
[2022-09-01T17:32:31.262+0000][110.832s][info][gc] GC(15) Pause Young (Normal) (G1 Evacuation Pause) 486M->130M(4096M) 93.914ms
[2022-09-01T17:33:48.974+0000][188.545s][info][gc] GC(16) Pause Young (Normal) (G1 Evacuation Pause) 1240M->169M(4096M) 26.671ms
.
.
.
Start and End Time
Freed memory
Overhead
Frequency
Allocation Rate
Pause Time
80. NEXT
● Wake Up every x ms
● measure amount time passed
● https://github.com/giltene/jHiccup
80
Latency - Hiccup Probe (inspired by jHiccup)
T T+x + p
{
Sleep X ms
81. NEXT
● GC logs and - System.gc()
● Histogram of live set : jmap -histo:live <PID>
● Grab a Heap dump (or at least a heap histogram)
81
Estimate Live Set
82. NEXT
● Long lasting memory ( maybe slowly changing)
● Service with large state will benefit from generational GC
● If State is bigger than old gen …. very bad
82
Live set - Long lasting - state
92. NEXT
● Compacting GC should not have fragmentation
● What about humongous objects ?
● G1 handles it poorly
● ZGC Does better
92
Fragmentation
93. NEXT
● long term state should fit in old gen
● short term memory should not spill to old gen
93
Generational GC anomalies
New Generation Old Generation
Application State
94. NEXT
94
Your Service Questionnaire:
Question Value
Heap size the process is using (-Xmx)
GC overhead over an hour of peak time
Max Pause Time over a 24 hour period
Number of collections above GC pause time targets
Live set size (MB)
Allocation Rate