Подтвердить что ты не робот

Выводит ли ОС обратно ОС на ОС?

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

В результате фактическая память процесса никогда не уменьшится. В статье, которая напомнила мне об этом, и Javas Runtime написано на C/С++, поэтому я думаю, что то же самое относится?

Обновление
Мой вопрос касается Java. Я упоминаю C/С++, так как я предполагаю, что выделение/освобождение Javas выполняется JRE с использованием некоторой формы malloc/delete

4b9b3361

Ответ 1

HotSpot JVM действительно высвобождает память обратно в ОС, но делает это неохотно, поскольку изменение размера кучи обходится дорого, и предполагается, что если вам понадобится эта куча, то она понадобится вам снова.

Вы можете сделать его более агрессивным, установив -XX:GCTimeRatio=19 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=30, что позволит ему тратить больше процессорного времени на сбор и ограничивать объем выделенной, но неиспользуемой памяти кучи после цикла GC.

Предполагая, что вы используете параллельный сборщик, вы также можете установить -XX:InitiatingHeapOccupancyPercent=N с N на какое-то низкое значение, чтобы позволить GC запускать параллельные коллекции почти непрерывно, что потребляет еще больше циклов ЦП, но быстрее сокращает кучу. Как правило, это не очень хорошая идея, но на некоторых типах машин с большим количеством запасных ядер ЦП, но нехваткой памяти, это может иметь смысл.

Если вы используете коллектор с заданным по умолчанию заданием времени паузы (CMS или G1), вы также можете ослабить эту цель, чтобы наложить на коллектор меньше ограничений, или вы можете переключить параллельный коллектор, чтобы расставить приоритеты по сравнению со временем паузы.

Кроме того, с Java 9 можно использовать опцию -XX:-ShrinkHeapInSteps, чтобы более агрессивно применять сжатие, вызванное двумя предыдущими опциями. Соответствующая ошибка OpenJDK.

Обратите внимание, что способность к усадке и поведение зависят от выбранного сборщика мусора. Например, G1 получил возможность возвращать неиспользуемые куски в середине кучи с помощью jdk8u20, в то время как ZGC делал с jdk13 и сборщиком эпсилона, скорее всего, никогда не будет.
Поэтому, если требуется сжатие кучи, его следует протестировать для конкретной версии JVM и конфигурации GC.

Ведение журнала GC с помощью PrintAdaptiveSizePolicy также может помочь понять, например, когда JVM пытается использовать больше памяти для молодого поколения для достижения некоторых целей.

Также есть JEP 346, включенный в OpenJDK 12, который вводит быстрое освобождение памяти для G1GC с опцией G1PeriodicGCInterval, опять же за счет некоторого дополнительного CPU. Также упоминаются похожие функции в Shenandoah и OpenJ9 VM.

Ответ 2

JVM выпускает обратно память при некоторых обстоятельствах, но (по соображениям производительности) это не происходит, когда какая-либо память собирает мусор. Это также зависит от JVM, OS, сборщика мусора и т.д. Вы можете наблюдать за потреблением памяти вашего приложения с помощью JConsole, VisualVM или другого профилировщика.

Также см. этот связанный отчет об ошибках

Ответ 3

Если вы используете сборщик G1 и время от времени вызываете System.gc() (я делаю это раз в минуту), Java надежно сократит кучу и вернет память операционной системе.

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

Я рекомендую использовать эти параметры в сочетании с приведенным выше предложением для очень компактного резидентного размера процесса:

-XX:+UseG1GC -XX:MaxHeapFreeRatio=30 -XX:MinHeapFreeRatio=10

Ежедневно в течение нескольких месяцев эти параметры использовались в большом приложении (целой гостевой ОС на основе Java) с динамически загружаемыми и выгружаемыми классами, а процесс Java почти всегда оставался в пределах 400–800 МБ.

Изменение: JDK 12 будет иметь коллектор G1 вернуть память в ОС (без вызова System.gc) ", когда приложение находится в режиме ожидания". Последний термин, кажется, определен для серверных приложений, но, возможно, он будет работать и для настольных компьютеров и/или они сделают его настраиваемым.

Ответ 4

в этой статье здесь объясняется, как GC работает на Java 7. В двух словах есть много разных сборщиков мусора, Обычно память хранится для процесса Java, и только некоторые GC выпускают ее в систему (по вашему запросу). Но память, используемая процессом Java, не будет расти бесконечно, так как существует верхний предел, определяемый параметром Xmx (обычно это 256 м, но я думаю, что это зависит от ОС/машины).

Ответ 5

ZGC выпущена в 13 java и может возвращать неиспользованную кучу памяти операционной системе Пожалуйста, смотрите ссылку