Weitere ähnliche Inhalte
Ähnlich wie Garbage First Garbage Collector: Where the Rubber Meets the Road! (20)
Mehr von Monica Beckwith (7)
Kürzlich hochgeladen (20)
Garbage First Garbage Collector: Where the Rubber Meets the Road!
- 2. ©2017 CodeKaram
About me
• Java performance engineer
• President @Code Karam LLC
• Partner @Extreme Performance Experts
• I have worked with Oracle, Sun, AMD …
• I used to work in the capacity of G1 GC
performance lead @Oracle.
2
- 4. ©2017 CodeKaram
Agenda
• Tuning considerations with G1 GC
• Taming mixed GCs
• Components of a G1 GC pause
• Humongous object requirements
• Fragmentation
• Evacuation failures
• Allocation rate and promotion rate
4
- 9. ©2017 CodeKaram
G1 GC Heap Regions
• Young Regions - Regions that contain objects in
the Eden and Survivor Spaces
• Old Regions - Regions that contain objects in
the Old generation.
• Humongous Regions - Regions that contain
Humongous Objects.
9
- 20. ©2017 CodeKaram
Collection Set
• A young collection set (CSet) will incorporate all
the young regions
• A mixed collection set will incorporate all the
young regions and a few candidate old regions
based on the “most garbage first” principle.
20
- 25. ©2017 CodeKaram
• Maintain and track incoming references into its
region
• old-to-young references
• old-to-old references
• Remembered sets have varying granularity
based on the “popularity” of objects or regions.
25
Remembered Sets
- 26. ©2017 CodeKaram26
Figure 2.3 Remembered sets with incoming object references**
<insert G1-Deep-Dive-Figure-3.tif>
empty region young region old region
incoming reference into a region
incoming reference into an RSet’s owning region
RSet for Region y
RSet for Region z
Region z
Region x Region y
RSet for Region x
<insert G1-Deep-Dive-Figure-3.tif>
Figure G1-Deep-Dive-Figure-3: RSet example for one young and two old regions.
G1 GC has its way of handling such demands of popularity and it does so by changing the
density of RSets. The density of RSets follow three levels of granularity namely; sparse, fine and
coarse. For a popular region, the RSet would probably get coarsened to accommodate the pointers
from various other regions. This will be reflected in the RSet scanning time for those regions.
LEGENDS
empty region young region old region
incoming reference into a region
incoming reference into an RSet’s owning region
RSet for Region y
RSet for Region z
Region z
Region x Region y
RSet for Region x
- 28. ©2017 CodeKaram
G1 GC - Pause Histogram
28
Pausetimeinmilliseconds
0
30
60
90
120
Timestamps
3415 3416.3 3417.2 3418.4 3419 3422 3423.4 3432.2 3433.2 3436.8 3437.6 3438.9 3440
Young Collection Initial Mark Remark Cleanup Mixed Collection
Occupancy == Initiating Heap Occupancy Percent
- 35. ©2017 CodeKaram
Initiating Heap Occupancy
Percent
35
• Threshold to start the concurrent marking cycle
to identify candidate old regions.
• When old generation occupancy crosses this
adaptive threshold.
• Based on the total heap size.
- 38. ©2017 CodeKaram
Stages of Concurrent
Marking
38
• Initial-mark
• Root region scan
• Concurrent mark
• Remark / Final mark
• Cleanup
- 39. ©2017 CodeKaram
Class Unloading with
Concurrent Mark
• With JDK 8 update 40, you have
ClassUnloadingWithConcurrentMark, and
unreachable classes can be unloaded during
Remark.
39
- 48. ©2017 CodeKaram
Say,
The young collections are meeting your SLAs,
but…
The mixed collections are far too frequent and
too many
OR
The mixed collections are blowing your SLAs
48
Why Tame Mixed
Collections?
- 50. ©2017 CodeKaram
If meeting the latency SLA is your only concern:
Divide the expensive collection further into
smaller inexpensive collections
50
What Can We Do?
- 51. ©2017 CodeKaram
Adjusting Each Mixed
Collection
51
Minimum number of old regions to
be included in the mixed collection
set.
Maximum number of old regions to
be included in the mixed collection
set.
- 53. ©2017 CodeKaram
If the GC overhead is too high and you have heap
to spare (after considering your humongous
objects requirements):
Remove the expensive regions from your
collection set
53
What Can We Do?
- 54. ©2017 CodeKaram
Eliminating Expensive Old
Regions From Mixed Collections
• You could eliminate based on the liveness per
old region
• You could also eliminate expensive old regions
towards the end of the sorted array
54
- 62. ©2017 CodeKaram
, 0.4066560 secs]
[Parallel Time: 354.9 ms, GC Workers: 48]
[GC Worker Start (ms): Min: 4500060.2, Avg: 4500068.1, Max: 4500085.2, Diff: 24.9]
[Ext Root Scanning (ms): Min: 0.0, Avg: 4.8, Max: 31.8, Diff: 31.8, Sum: 231.0]
[Update RS (ms): Min: 0.0, Avg: 21.6, Max: 116.3, Diff: 116.3, Sum: 1036.3]
[Processed Buffers: Min: 0, Avg: 4.9, Max: 29, Diff: 29, Sum: 234]
[Scan RS (ms): Min: 0.0, Avg: 41.5, Max: 62.3, Diff: 62.2, Sum: 1992.1]
[Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.3]
[Object Copy (ms): Min: 195.6, Avg: 233.1, Max: 261.1, Diff: 65.5, Sum: 11189.0]
[Termination (ms): Min: 21.0, Avg: 45.6, Max: 74.4, Diff: 53.4, Sum: 2188.5]
[GC Worker Other (ms): Min: 0.0, Avg: 0.1, Max: 0.2, Diff: 0.2, Sum: 4.8]
[GC Worker Total (ms): Min: 329.6, Avg: 346.7, Max: 354.7, Diff: 25.1, Sum: 16642.0]
[GC Worker End (ms): Min: 4500414.7, Avg: 4500414.8, Max: 4500415.0, Diff: 0.2]
62
- 63. ©2017 CodeKaram
[Code Root Fixup: 0.1 ms]
[Code Root Migration: 0.2 ms]
[Clear CT: 1.4 ms]
[Other: 50.1 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 34.6 ms]
[Ref Enq: 0.3 ms]
[Free CSet: 7.5 ms]
63
- 64. ©2017 CodeKaram
[Code Root Fixup: 0.1 ms]
[Code Root Migration: 0.2 ms]
[Clear CT: 1.4 ms]
[Other: 50.1 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 34.6 ms]
[Ref Enq: 0.3 ms]
[Free CSet: 7.5 ms]
64
- 65. ©2017 CodeKaram
, 0.4066560 secs]
[Parallel Time: 354.9 ms, GC Workers: 48]
[GC Worker Start (ms): Min: 4500060.2, Avg: 4500068.1, Max: 4500085.2, Diff: 24.9]
[Ext Root Scanning (ms): Min: 0.0, Avg: 4.8, Max: 31.8, Diff: 31.8, Sum: 231.0]
[Update RS (ms): Min: 0.0, Avg: 21.6, Max: 116.3, Diff: 116.3, Sum: 1036.3]
[Processed Buffers: Min: 0, Avg: 4.9, Max: 29, Diff: 29, Sum: 234]
[Scan RS (ms): Min: 0.0, Avg: 41.5, Max: 62.3, Diff: 62.2, Sum: 1992.1]
[Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.3]
[Object Copy (ms): Min: 195.6, Avg: 233.1, Max: 261.1, Diff: 65.5, Sum:
11189.0]
[Termination (ms): Min: 21.0, Avg: 45.6, Max: 74.4, Diff: 53.4, Sum: 2188.5]
[GC Worker Other (ms): Min: 0.0, Avg: 0.1, Max: 0.2, Diff: 0.2, Sum: 4.8]
[GC Worker Total (ms): Min: 329.6, Avg: 346.7, Max: 354.7, Diff: 25.1, Sum: 16642.0]
[GC Worker End (ms): Min: 4500414.7, Avg: 4500414.8, Max: 4500415.0, Diff: 0.2]
65
- 69. ©2017 CodeKaram
Ideally, humongous objects are few in
number and are short lived.
A lot of long-lived humongous objects can
cause evacuation failures since humongous
regions add to the old generation occupancy.
69
Humongous Objects
- 71. ©2017 CodeKaram
Humongous Objects:
• Are allocated out of the old generation
• Are not moved
*Note: Since JDK8 update 40, they can be
collected during a young collection
71
So, What Did We Observe?
- 73. ©2017 CodeKaram
Humongous objects can pose the following issues:
Wasted space
Evacuation failures due to not having enough
(to-space) regions
73
So, What Did We Observe?
- 75. ©2017 CodeKaram
• G1 GC is designed to “absorb” some
fragmentation.
• Default is 5% of the total Java heap
• Tradeoff so that expensive regions are left out.
G1 Heap Waste Percentage
75
- 76. ©2017 CodeKaram
G1 Mixed GC (Region)
Liveness Threshold
76
• G1 GC’s old regions are also designed to
“absorb” some fragmentation.
• Default is 85% liveness in a G1 region.
• Tradeoff so that expensive regions are left out.
- 81. ©2017 CodeKaram
Evacuation Failures
81
276.731: [GC pause (G1 Evacuation Pause) (young) (to-space exhausted),
0.8272932 secs]
[Parallel Time: 387.0 ms, GC Workers: 8]
<snip>
[Code Root Fixup: 0.1 ms]
[Code Root Purge: 0.0 ms]
[Clear CT: 0.2 ms]
[Other: 440.0 ms]
[Evacuation Failure: 437.5 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 0.1 ms]
[Ref Enq: 0.0 ms]
[Redirty Cards: 0.9 ms]
[Humongous Reclaim: 0.0 ms]
[Free CSet: 0.9 ms]
[Eden: 831.0M(900.0M)->0.0B(900.0M) Survivors: 0.0B->0.0B Heap: 1020.1M(1024.0M)-
>1020.1M(1024.0M)]
[Times: user=3.64 sys=0.20, real=0.83 secs]
**
- 82. ©2017 CodeKaram
• When there are no more regions available for
survivors or tenured objects, G1 GC encounters
an evacuation failure.
• An evacuation failure is expensive and the usual
pattern is that if you see a couple of evacuation
failures; full GC could* soon follow.
82
Evacuation Failures
- 83. ©2017 CodeKaram
A heavily tuned JVM command line
may be restricting the G1 GC
ergonomics and adaptability.
Start with just your heap sizes and a
reasonable pause time goal
83
Avoiding Evacuation
Failures
- 84. ©2017 CodeKaram
Your live data set + long live
transient data may be too large for
the old generation
Check LDS+ and increase heap to
accommodate everything in the old
generation.
84
Avoiding Evacuation
Failures
- 85. ©2017 CodeKaram
Initiating Heap Occupancy Threshold
could be the issue.
Check IHOP and make sure it accommodates
the LDS+.
IHOP threshold too high -> Delayed marking ->
Delayed incremental compaction -> Evacuation
Failures!
85
Avoiding Evacuation
Failures
- 86. ©2017 CodeKaram
Marking Cycle could be taking too
long to complete?
Increase concurrent marking threads
Reduce IHOP
86
Avoiding Evacuation
Failures
- 87. ©2017 CodeKaram
to-space survivors are the problem?
Increase the G1ReservePercent, if to-space
survivors are triggering the evacuation
failures!
87
Avoiding Evacuation
Failures
- 91. ©2017 CodeKaram
• 487.817: [G1Ergonomics (Heap Sizing) attempt heap
expansion, reason: region allocation request failed, allocation
request: 524280 bytes]
• 487.817: [G1Ergonomics (Heap Sizing) expand the heap,
requested expansion amount: 524280 bytes, attempted
expansion amount: 1048576 bytes]
• 487.817: [G1Ergonomics (Heap Sizing) did not expand the
heap, reason: heap already fully expanded]
• 487.888: [G1Ergonomics (Heap Sizing) attempt heap
expansion, reason: recent GC overhead higher than threshold
after GC, recent GC overhead: 28.40 %, threshold: 10.00 %,
uncommitted: 0 bytes, calculated expansion amount: 0 bytes
(20.00 %)]
91
- 92. ©2017 CodeKaram
• 487.817: [G1Ergonomics (Heap Sizing) attempt heap
expansion, reason: region allocation request failed, allocation
request: 524280 bytes]
• 487.817: [G1Ergonomics (Heap Sizing) expand the heap,
requested expansion amount: 524280 bytes, attempted
expansion amount: 1048576 bytes]
• 487.817: [G1Ergonomics (Heap Sizing) did not expand the
heap, reason: heap already fully expanded]
• 487.888: [G1Ergonomics (Heap Sizing) attempt heap
expansion, reason: recent GC overhead higher than threshold
after GC, recent GC overhead: 28.40 %, threshold: 10.00 %,
uncommitted: 0 bytes, calculated expansion amount: 0 bytes
(20.00 %)]
92