JVM G1GC смешанный gc не собирает много старых регионов
Мой сервер использует 1.8.0_92 в CentOS 6.7, параметр GC - "-Xms16g -Xmx16g -XX: + UseG1GC". Поэтому значение InitiatingHeapOccupancyPercent по умолчанию равно 45, значение G1HeapWastePercent равно 5, а значение G1MixedGCLiveThresholdPercent равно 85. Мой смешанный GC для сервера начинается с 7,2 ГБ, но он очищается все меньше и меньше, в конце концов старый gen остается большим, чем 7,2 ГБ, поэтому он всегда пытается выполнить одновременную метку. Наконец все кучи исчерпаны и полный GC произошел. После полной GC, старый используемый ген под 500 МБ.
![old gen]()
Мне любопытно, почему мой смешанный GC не может собирать больше, похоже, что живых данных не так уж много...
Я попытался напечатать информацию, связанную с g1, и обнаружил, что многие сообщения, подобные ниже, выглядят так, будто мой старый поколение содержит много живых данных, но почему полный GC может собирать так много...
G1Ergonomics (Mixed GCs) do not continue mixed GCs, reason: reclaimable percentage not over threshold, candidate old regions: 190 regions, reclaimable: 856223240 bytes (4.98 %), threshold: 5.00 %
Ниже в журнале приведен результат изменения InitiatingHeapOccupancyPercent до 15 (начать параллельную отметку на 2,4 ГБ) для ускорения.
### PHASE Post-Marking
......
### SUMMARY capacity: 16384.00 MB used: 2918.42 MB / 17.81 % prev-live: 2407.92 MB / 14.70 % next-live: 2395.00 MB / 14.62 % remset: 56.66 MB code-roots: 0.91 MB
### PHASE Post-Sorting
....
### SUMMARY capacity: 1624.00 MB used: 1624.00 MB / 100.00 % prev-live: 1123.70 MB / 69.19 % next-live: 0.00 MB / 0.00 % remset: 35.90 MB code-roots: 0.89 MB
РЕДАКТИРОВАТЬ:
Я пытаюсь запустить полный сборщик мусора после смешанного сборщика мусора, он все еще может уменьшиться до 4xx МБ, так что, похоже, мой старый ген может собрать больше данных.
![enter image description here]()
до полного gc, смешанный лог gc
32654.979: [G1Ergonomics (Mixed GCs) start mixed GCs, reason: candidate old regions available, candidate old regions: 457 regions, reclaimable: 2956666176 bytes (17.21 %), threshold: 5.00 %], 0.1106810 secs]
....
[Eden: 6680.0M(6680.0M)->0.0B(536.0M) Survivors: 344.0M->280.0M Heap: 14.0G(16.0G)->7606.6M(16.0G)]
[Times: user=2.31 sys=0.01, real=0.11 secs]
...
[GC pause (G1 Evacuation Pause) (mixed)
...
32656.876: [G1Ergonomics (CSet Construction) finish adding old regions to CSet, reason: old CSet region num reached max, old: 205 regions, max: 205 regions]
32656.876: [G1Ergonomics (CSet Construction) finish choosing CSet, eden: 67 regions, survivors: 35 regions, old: 205 regions, predicted pause time: 173.84 ms, target pause time: 200.00 ms]
32656.992: [G1Ergonomics (Mixed GCs) continue mixed GCs, reason: candidate old regions available, candidate old regions: 252 regions, reclaimable: 1321193600 bytes (7.69 %), threshold: 5.00 %]
[Eden: 536.0M(536.0M)->0.0B(720.0M) Survivors: 280.0M->96.0M Heap: 8142.6M(16.0G)->6029.9M(16.0G)]
[Times: user=2.49 sys=0.01, real=0.12 secs]
...
[GC pause (G1 Evacuation Pause) (mixed)
...
32659.727: [G1Ergonomics (CSet Construction) finish adding old regions to CSet, reason: reclaimable percentage not over threshold, old: 66 regions, max: 205 regions, reclaimable: 857822432 bytes (4.99 %), threshold: 5.00 %]
32659.727: [G1Ergonomics (CSet Construction) finish choosing CSet, eden: 90 regions, survivors: 12 regions, old: 66 regions, predicted pause time: 120.51 ms, target pause time: 200.00 ms]
32659.785: [G1Ergonomics (Mixed GCs) do not continue mixed GCs, reason: reclaimable percentage not over threshold, candidate old regions: 186 regions, reclaimable: 857822432 bytes (4.99 %), threshold: 5.00 %]
[Eden: 720.0M(720.0M)->0.0B(9064.0M) Survivors: 96.0M->64.0M Heap: 6749.9M(16.0G)->5572.0M(16.0G)]
[Times: user=1.20 sys=0.00, real=0.06 secs]
РЕДАКТИРОВАТЬ: 2016/12/11
Я сбросил кучу с другой машины с -Xmx4G
.
Я использовал салат в качестве моего клиента Redis, и он использует отслеживание с помощью LatencyUtils. Это делает LatencyStats (который содержит несколько long[]
с почти 3000 элементами) слабыми ссылками на экземпляры каждые 10 минут (Сброс задержек после публикации по умолчанию равен true, https://github.com/mp911de/lettuce/wiki/Command-Latency-Metrics). Так что после долгого времени он будет делать много слабых ссылок на LatencyStats.
До полной GC. ![afterFullGc]()
![afterFullGc]()
![afterFullGc]()
После полной GC. ![afterFullGc]()
В настоящее время мне не нужно отслеживать с салата, так что просто отключите его, и он больше не имеет полного GC. Но не уверен, почему смешанный gc не очищает их.
Ответы
Ответ 1
ну, вы не упомянули все аргументы, которые вы задали, но
Вы могли бы попытаться установить
-XX:+ScavengeBeforeFullGC
и вам также следует подумать о жизненном цикле вашего Object
. как долго ваши приложения Object
живой и какой размер являются Object
s.
подумайте об этом и взгляните на следующие аргументы
-XX:NewRatio=n old/new ration (default 2)
-XX:SurvivorRatio=n eden/survivor ratio (default 8)
-XX:MaxTenuringThreshold=n number of times, objects are moved from survivor one to survivor two and vice versa before objects are moved to old-gen (default 15)
со значениями по умолчанию Xms и Xmx установлены в 32gb → old gen = 16gb и new gen 16gb → eden 14gb → оставшиеся в живых 2gb (есть два, каждый из которых имеет размер 1gb)
eden содержит все Object
, которые создаются new Object
.
один оставшийся в живых (оставшийся в живых) всегда пуст. другие (из-оставшегося в живых) содержит Object
который пережил незначительный GC
оставшийся в живых Object
из Эдема и из оставшегося в живых переходит в оставшийся в живых в несовершеннолетнем
если стандартный размер 1 ГБ этой 'конфигурации по умолчанию' превышает, Object
переходит в old-gen
если оно не превышает, после 15 -XX:MaxTenuringThreshold
gc (-XX:MaxTenuringThreshold
умолчанию -XX:MaxTenuringThreshold
) Object
переходит в old-gen
изменяя эти значения, всегда имейте в виду, old-gen должен быть таким же большим или большим, как new-gen, потому что gc может заставить весь new-gen перейти в old-gen
редактировать
была бы полезна временная шкала вашего первого изображения "old gen: used"
имейте в виду, что нет необходимости делать полный gc, пока старый gen не превысит - полный gc заставляет весь "мир" останавливаться на определенный период времени
в этом конкретном случае, я бы сказал, что вы могли бы
- уменьшить
-Xms
и -Xmx
до 8 -Xmx
- установить/уменьшить
-XX:SurvivorRatio
значение -XX:SurvivorRatio
до 2 - установить/увеличить
-XX:MaxTenuringThreshold
до 50
и вы получите старый и новый ген, каждый размером 4 ГБ,
Eden размером 2 ГБ,
два выживших, каждый размером 1Гб,
и примерно 50 второстепенных, прежде чем Object
войдет в старое поколение