Процесс java.exe использует больше памяти и не освобождает ее

У меня есть Java-приложение, которое в состоянии бездействия перед любым сложным выполнением использует 23 МБ в куче, а размер процесса java.exe в TaskManager составляет около 194 МБ. После некоторых сложных операций размер java.exe увеличился примерно до 500 МБ, а размер кучи также увеличился. Размер кучи уменьшается до 23 МБ после нескольких полных сборок мусора путем вызова метода System.gc(). Но размер java.exe уменьшился до примерно 237 МБ с 600 МБ, в которых все еще содержится около 43 МБ данных. Есть ли способ уменьшить это? Или это из-за какого-то поведения?

2 ответа

Решение

Это нормально, не волнуйся. JVM получает память, когда ей необходимо выполнить сложную логику. Когда Java завершит обработку задач, JVM все равно сохранит эту память как зарезервированное пространство и не будет возвращена обратно в ОС. Эта архитектура помогает в производительности, потому что JMV не должен снова запрашивать ту же память из базовой ОС. Он по-прежнему будет в диапазоне, который вы определили в параметре -Xmx JVM.

Смотрите эту ссылку IBM для некоторых интересных деталей. http://www-01.ibm.com/support/docview.wss?uid=swg21326774

К сожалению, это одна из серых областей JVM; у вас действительно нет большого контроля над тем, как ОС и JVM делят память между собой. Думайте о JVM как о виртуальной ОС, которая требует некоторой памяти для запуска. И ваша родительская ОС, и виртуальная машина жаждут ресурсов и хотят привязать к полученным ресурсам как можно больше памяти. Запрос большего объема памяти у ОС - это трудоемкая операция, поэтому большинство JVM не освобождают память обратно в ОС, даже если она больше не нужна.

См. Этот документ от Oracle для получения дополнительной информации об управлении внутренней памятью JVM. http://www.oracle.com/technetwork/java/javase/memorymanagement-whitepaper-150215.pdf

Я бы посоветовал вам сначала прочитать ссылку на IBM, а затем вы можете погрузиться в странный мир памяти, описанный в официальном документе. Обе эти ссылки очень информативны и интересны.

ОС след Java процесса составлены из

  • куча Java (его размер ограничен -Xmx)
  • метаданные, относящиеся к Java-классам (или постоянная генерация в HotSpot JVM)
  • память без кучи, доступная через NIO
  • пространство стека для Java-потоков

Некоторые алгоритмы сборки мусора возвращают свободную память обратно в ОС, другие - нет. В HotSpot JVM последовательный старый сборщик пространства (обычно включенный по умолчанию) возвращает память обратно в ОС (так что вы можете увидеть сокращение процесса). Хотя, другой коллекционер, такой как -XX:+UseParallelOldGC или же -XX:+UseConcMarkSweepGC никогда не вернет неиспользованную кучу памяти в ОС.

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

Другие вопросы по тегам