Java - Почему G C раз увеличивается с ростом кучи (с точки зрения емкости)? - PullRequest
0 голосов
/ 29 февраля 2020

По крайней мере, в старых GC, это верно. (Я знаю, что есть новые, такие как ZG C и Shenandoah, которые стремятся устранить это)

Насколько я знаю, G C отслеживает живые объекты, поэтому не следует G C время больше всего будет зависеть от количества объектов (живых / нуждающихся в очистке)?

РЕДАКТИРОВАТЬ: Я имел в виду, растет с точки зрения емкости, то есть большая куча, но то же самое использование его применение

Ответы [ 2 ]

0 голосов
/ 04 марта 2020

Существует множество различных алгоритмов, которые можно использовать для реализации сборки мусора. Не все из них демонстрируют поведение, которое вы упоминаете.

В случае вашего вопроса вы имеете в виду алгоритмы, которые используют форму разметки. Если мы возьмем JSM HostSpot в качестве примера, старое поколение может быть собрано с помощью сборщика CMS. При этом используется фаза маркировки, на которой помечаются все объекты, доступные из кода приложения. Первоначально создается root набор непосредственно доступных объектов (ссылки на объекты в стеке, регистры и т. Д. c.). Каждый объект в этом наборе имеет бит метки, установленный в его заголовке, чтобы указать, что он все еще используется. Все ссылки из этих объектов отслеживаются рекурсивно, и в конечном итоге каждый доступный объект имеет установленный бит метки. Время, необходимое для этого, пропорционально количеству живых объектов, а не размеру кучи.

Затем фаза развертки должна охватить всю кучу, найти объекты с установленным битом метки и определить промежутки между ними, чтобы их можно было добавлять в свободные списки. Они используются для выделения места для объектов, продвигаемых молодым поколением. Так как вся куча должна быть очищена, время, которое занимает , пропорционально размеру кучи, независимо от того, сколько данных в куче находится в реальном времени.

В случае G1, алгоритм аналогичен, но каждое поколение кучи разделено на регионы, чтобы пространство можно было использовать более эффективным образом.

0 голосов
/ 29 февраля 2020

Разве вы не ответили на свой вопрос?

Насколько я знаю, G C отслеживает живые объекты, поэтому не должно ли время G C быть в основном затронуто количество объектов (живых / нужно очистить)?

Чем больше растет куча, тем больше у нее живых объектов, тем медленнее G C (я уверен, что есть исключения к этому правилу, в частности для небольших коллекций, но это грубая идея). Количество очищаемых объектов не имеет значения, больше всего важно общее количество живых объектов. Теперь, если ваша куча растет из-за того, что вы храните долгоживущие объекты, это может быть хорошо, если вы не будете добавлять их все больше и больше. В конце концов, долгоживущие объекты будут перемещаться в сторону выжившего пространства и будут подчиняться только крупным коллекциям, а не второстепенным. Пока младший G C всегда достигает достаточного освобождения памяти от молодого поколения, основной G C не будет срабатывать на всех объектах (включая долгоживущие).

У меня также есть наблюдал другое поведение с G1. У нас было приложение с низкой задержкой (40 мс на стр. 99), поэтому мы попытались настроить G1 на очень короткие паузы (не помню, сколько, возможно, 5 мс или около того). Случилось так, что G1 более или менее соответствовал цели 5 мс, но он должен был работать очень часто, потому что 5 мс было недостаточно, чтобы справиться со всеми мертвыми объектами, которые у нас были в куче. Следовательно, нельзя сказать, что отдельные циклы сборки мусора будут медленнее с увеличением размера кучи, однако среднее время, затрачиваемое на сборку мусора за определенный период времени, скорее всего увеличится.

...