Можно ли освободить память для системы с Sun JVM после запуска GC?

В операционной системе работает 10 виртуальных машин JVM. На самом деле большинство ничего не делает — время от времени просто делает работу. Каждый процесс выделяет 600 МБ системной памяти. Я знаю, что физически можно использовать практически до 100 МБ. Остальные 500 МБ для каждого из этих процессов — это память, управляемая JVM (OldGen и т. д.). К сожалению, в моей системе всего 2 ГБ ОЗУ, и в результате большая часть выделенной памяти попадает в своп. Это значит, что когда приходит время одной из машин — первой, своп считывается в системную память за десятки секунд.

Есть ли способ заставить JVM освободить память для операционной системы после выполнения задачи? Например, GC будет запускаться каждые 1-5 минут, и в результате память процесса будет освобождена для системы.

Я использую: Linux x86_64 SMP, Java HotSpot (TM) 64-битный сервер VM 1.6.0


person Max    schedule 26.04.2012    source источник
comment
Я думаю, что это дубликат: stackoverflow.com/questions/324499/   -  person Denys Séguret    schedule 26.04.2012
comment
В качестве точности: я никогда не находил конкретной спецификации по этой теме, но я видел (в Linux) память, освобождаемую процессом (но не много).   -  person Denys Séguret    schedule 26.04.2012
comment
Почему вам нужны отдельные JVM для задач - почему вы не можете просто использовать кратковременную задачу, которая запускается в пул потоков (используя конструкцию ExecutorService java.util.concurrent)?   -  person kittylyst    schedule 27.04.2012
comment
Я не могу использовать ExecutorService java.util.concurrent, потому что это не проблема разработки. Я уже предоставил решение, написанное на Java (в виде jar-файлов), для работы в моей операционной системе. У меня нет возможности изменить эти банки или классы.   -  person Max    schedule 18.05.2012


Ответы (2)


Это значит, что когда приходит время одной из машин — первой, своп считывается в системную память за десятки секунд.

Страницы памяти заменяются только при доступе к ним. Если бы 500 МБ, о которых вы говорите, были действительно «свободны» с точки зрения JVM, они не оказались бы замененными. Должна быть причина, по которой JVM касается этой памяти. Одна из возможностей состоит в том, что он не совсем бесплатный, а содержит живые объекты.

Я бы порекомендовал:

  1. Использование профилировщика памяти (YourKit или VisualVM), чтобы увидеть фактическое использование памяти JVM.
  2. Возможно изменение размера кучи с помощью -Xmx.
person NPE    schedule 26.04.2012

Я не эксперт в вопросах производительности, но позвольте мне помочь вам с этим.

Существует вызов системы сбора мусора System.gc(). Если вы обратитесь к официальной документации по классу System (http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/System.html), он сообщит вам, что этот метод запускает сборку мусора.

Тем не менее, если вы обратитесь к Интернету (например, Когда System.gc() что-нибудь делает) вы увидите, что этот вызов МОЖЕТ вызывать систему сборки мусора. Мой личный опыт согласуется с этим постом.

Поскольку управление памятью автоматизировано, система сборки мусора сделает все возможное, чтобы хорошо управлять памятью за вас. Алгоритмы управления довольно эффективны, и попытки их перехитрить обычно не приносят хороших результатов.

Вы заявили, что большинство машин ничего не делают — следовательно, почему бы не «убить» их и не запустить новую, когда у вас есть работа? Разве это не будет эффективнее?

person rlinden    schedule 26.04.2012
comment
О, да! Было бы здорово, но я забыл сказать, что у процессов были внутренние триггеры, а не внешние. Поэтому JVM пришлось запускать, потому что никто другой не знает, когда срабатывает :-) - person Max; 26.04.2012