Почему мое общее использование памяти JVM более чем в 30 раз превышает его значение Xmx?

Я запускаю приложение Java с максимальным размером кучи 128 МБ (-Xmx128M). Он успешно завершается без OutOfMemoryError или любого другого необработанного исключения. Поэтому я предполагаю, что его фактический размер кучи оставался в пределах объявленного предела в 128 МБ.

Однако, наблюдая за процессом для этого приложения Java, я вижу, что максимальное использование памяти составляет 4 188 548 КБ (~ 4 ГБ). Это рост более чем в 30 раз превышающий контролируемый максимальный размер кучи. Хотя я понимаю, что это значение включает выделенную виртуальную память, которая может быть значительно больше, чем фактическая используемая физическая память, она затрагивает жесткие ограничения, например, установленные Sun Grid Engine, и поэтому она имеет смысл.

Как это возможно? Я понимаю, что общая память, потребляемая JVM, имеет немного больше, чем размер кучи, но я не понимаю, как ей может понадобиться несколько ГБ дополнительной памяти, кроме того, что приложение действительно нужно для создания своих объектов и выполнения его вычислений.

Я использую Sun Java 1.6.0.31, в 64-разрядном дистрибутиве RHEL Linux.

1 ответ

Есть несколько областей памяти, кроме кучи Java, управляемых -Xmx:

  • Стеки потоков
  • Пространство PermGen
  • direct ByteBuffers и отображается ByteBuffer
  • память, выделенная собственным кодом/библиотеками

Не зная подробностей вашей системы, я бы предположил, что что-то использует сопоставленный ByteBuffers.

Но вы могли бы разобраться в проблеме, просмотрев вывод команды pmap. В нем перечислены все области памяти процесса вместе с именами файлов, к которым привязана любая область (если, конечно, области отображаются).

licensed under cc by-sa 3.0 with attribution.