Как Jvm6 уменьшает размер кучи, когда это не нужно
Я наблюдаю за Java-приложением, запущенным на Jvm 6
, Вот скриншот панели jvisualVM 1.
Я замечаю, что когда размер кучи небольшой (до 12:39 на рисунке), сборщик мусора часто запускается. Затем я запускаю задачу с дорогой памятью пару раз (с 12:39 до 12:41) и пространство кучи увеличивается. Почему с этого момента сборщик мусора работает реже?
Через час или более, если я избегу выполнения дорогостоящих задач в приложении, пространство кучи постепенно уменьшится. Почему используемое пространство кучи занимает так много времени, чтобы уменьшить?
Что я могу сделать, чтобы избежать такого поведения? У новой виртуальной машины Java8 другое поведение?
2 ответа
Что я могу сделать, чтобы избежать такого поведения?
Задавать -XX:MaxHeapFreeRatio=30 -XX:MinHeapFreeRatio=15
Это уменьшит размер кучи более агрессивно. Обратите внимание, что не все реализации GC возвращают память, которую они не используют, обратно в ОС. По крайней мере, G1 делает, но это не доступно на Java 6.
Поведение выглядит нормально.
До 12:39 на вашем прикрепленном снимке профиля не происходит много GC.
Затем вы запускаете свои задачи, и когда объекты, которые более недоступны, становятся подходящими для GC, они отмечаются разверткой и удаляются.
Вам не обязательно беспокоиться о размере кучи, если вы не используете слишком много и часто вылетаете из-за утечки памяти. GC позаботится об удалении подходящих объектов из кучи, и вы ограничены в том, как вы можете повлиять на GC (если, конечно, вы не переключите реализацию GC).
Каждый основной выпуск платформы включает в себя некоторые изменения / улучшения JVM и GC, но поведение приложения будет очень похожим в Hotspot 7/8. Попытайся.
Современные JVM имеют высоко оптимизированные сборщики мусора, и вам не нужно беспокоиться о том, как / когда она восстанавливает память, а больше о том, чтобы убедиться, что вы освобождаете объекты, чтобы они стали пригодными для сбора. Как часто после запуска возникают проблемы с нехваткой памяти?
Если вы получаете сбои из-за нехватки памяти, настройте JVM на создание дампа кучи при выходе: -XX: + HeapDumpOnOutOfMemoryError -XX: HeapDumpPath = date.hprof