Что работает в куче Си по сравнению с кучей Java в JVM среды HP-UX? - PullRequest
1 голос
/ 17 сентября 2008

У меня возникла специфическая проблема с некоторыми приложениями Java в среде HP-UX.

Для кучи установлено значение -mx512, но, просматривая области памяти для этого процесса Java с помощью gpm, он показывает, что используется более 1,6 ГБ памяти RSS, а 1,1 ГБ выделено для области DATA. Растет довольно быстро в течение 24-48 часов, а затем существенно замедляется, по-прежнему увеличиваясь на 2 МБ каждые несколько часов. Однако в куче Java нет признаков утечки.

Любопытно, как это было возможно, я немного исследовал и обнаружил эту переписку HP на утечки памяти в куче java и кучи c: http://docs.hp.com/en/JAVAPERFTUNE/Memory-Management.pdf

Мой вопрос заключается в том, что определяет, что запускается в куче C по сравнению с кучей Java, и для вещей, которые не проходят через кучу Java, как бы вы определили объекты, которые запускаются в куче C? Кроме того, кучи Java находится внутри кучи C?

Ответы [ 3 ]

4 голосов
/ 17 сентября 2008

Рассмотрим, из чего состоит процесс Java.

У вас есть:

  • JVM (программа на C)
  • Данные JNI
  • байт-коды Java
  • Данные Java

Примечательно, что они ВСЕ живут в куче C (куча JVM, естественно, является частью кучи C).

В куче Java есть просто байтовые коды Java и данные Java. Но в куче Java также есть «свободное место».

Типичная (т. Е. Sun) JVM только увеличивает Java Heap по мере необходимости, но никогда не сжимает ее. Как только он достигает своего определенного максимума (-Xmx512M), он перестает расти и имеет дело с тем, что осталось. Когда эта максимальная куча исчерпана, вы получаете исключение OutOfMemory.

То, что эта опция Xmx512M НЕ ДЕЛАЕТ, является ограничением общего размера процесса. Он ограничивает только часть кучи Java процесса.

Например, у вас может быть изобретенная Java-программа, которая использует 10 Мб кучи Java, но вызывает вызов JNI, который выделяет 500 Мб кучи C. Вы можете видеть, насколько велик размер вашего процесса, хотя куча Java мала. Кроме того, с помощью новых библиотек NIO вы также можете подключать память вне кучи.

Другим аспектом, который вы должны учитывать, является то, что Java GC обычно является «Копирующим коллектором». Это означает, что он берет «живые» данные из памяти, которую они собирают, и копирует их в другой раздел памяти. Это пустое пространство, которое копируется в НЕ ЧАСТЬ КУДА, по крайней мере, не с точки зрения параметра Xmx. Это, как «новая куча», и становится частью кучи после копирования (старое пространство используется для следующего GC). Если у вас куча 512 МБ, а она на 510 МБ, Java собирается куда-то скопировать живые данные. Наивная мысль была бы о другом большом открытом пространстве (например, 500+ МБ). Если бы все ваши данные были «живыми», то для копирования потребовался бы такой большой кусок.

Итак, вы можете видеть, что в самом крайнем случае вам необходимо как минимум удвоить объем свободной памяти в вашей системе для обработки определенного размера кучи. Как минимум 1 ГБ для кучи 512 МБ.

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

Наконец, обратите внимание, что JVM делает забавные вещи, такие как сопоставление классов rt.jar с виртуальной машиной, чтобы упростить запуск. Они отображаются в блоке только для чтения и могут использоваться другими процессами Java. Эти общие страницы будут «считаться» со всеми процессами Java, хотя на самом деле они потребляют физическую память только один раз (магия виртуальной памяти).

Теперь о том, почему ваш процесс продолжает расти, если вы никогда не обращаетесь к сообщению Java OOM, это означает, что ваша утечка НЕ ​​находится в куче Java, но это не значит, что она не может быть в другом месте (JRE среда выполнения, библиотека JNI стороннего производителя, собственный драйвер JDBC и т. д.).

2 голосов
/ 17 сентября 2008

Как правило, только данные в объектах Java хранятся в куче Java, вся другая память, требуемая для виртуальной машины Java, выделяется из кучи «native» или «C» (фактически, сама куча Java - это всего лишь одна непрерывный кусок, выделенный из кучи C).

Поскольку JVM требует, чтобы куча Java (или кучи, если используется сборочная сборка мусора) была непрерывной частью памяти, весь максимальный размер кучи (значение -mx) обычно выделяется во время запуска JVM. На практике Java VM будет пытаться свести к минимуму использование этого пространства, чтобы операционной системе не нужно было резервировать для нее реальную память (операционная система достаточно хитрая, чтобы знать, когда часть памяти никогда не записывалась) .

Таким образом, куча Java будет занимать определенный объем памяти.

Остальная часть хранилища будет использоваться Java VM и любым используемым кодом JNI. Например, JVM требует памяти для хранения байт-кода Java и пулов констант из загруженных классов, результата скомпилированного кода JIT, рабочих областей для компиляции кода JIT, стеков собственных потоков и других подобных типов.

JNI-код - это просто специфичный для платформы (скомпилированный) C-код, который может быть привязан к объекту Java в форме «нативного» метода. Когда этот метод выполняется, связанный код выполняется и может выделять память, используя стандартные подпрограммы C (например, malloc), которые будут использовать память в куче C.

0 голосов
/ 17 сентября 2008

Мое единственное предположение на основании приведенных вами цифр - утечка памяти в Java VM. Возможно, вы захотите попробовать одну из других виртуальных машин, перечисленных в упомянутой вами статье. Другой (гораздо более трудной) альтернативой может быть компиляция open java на платформе HP.

Java Sun еще не открыта на 100%, они работают над этим, но я считаю, что есть одна в sourceforge, которая есть.

Кстати, Java также побеждает память. Иногда это немного сбивает с толку управление памятью ОС (вы видите это, когда у окон заканчивается память и просит Java освободить часть, Java касается всех своих объектов, заставляя их загружаться из файла подкачки, окна кричат ​​в агонии и умирают), но Я не думаю, что это то, что вы видите.

...