Как рассчитать (и указать) общее пространство памяти, разрешенное для процесса Java? - PullRequest
4 голосов
/ 18 августа 2010

У меня есть система, которая не может обеспечить более 1,5 Гб для процесса Java.Таким образом, мне нужен точный способ указать настройки процесса Java, включая все виды памяти внутри Java и возможный разветвление.

Один конкретный java-процесс и система для иллюстрации моей проблемы:

Моя текущая среда - java 1.6.0_18 в Ubuntu Linux 9.10.

Я запускаю большой процесс java-сервера со следующимиПараметры JVM: "-Xms512m -Xmx1024m -XX: PermSize = 256m -XX: MaxPermSize = 512m"

Теперь команда "top" сообщает, что процесс использует память объемом 1,6 ГБ ...

Вопросы:

1 - как рассчитывается максимальное пространство, используемое процессом Java?Пожалуйста, предоставьте точную формулу, если это возможно.(Что-то вроде: max.heap + max.perm + стек + пространство jvm = максимальное пространство)

2 - каково печально известное поведение форка под linux в моем случае?Будет ли разветвленная JVM занимать дополнительные 1,6 ГБ (в результате чего будет использоваться 3,2 ГБ используемой памяти)?

3 - Какие параметры необходимо использовать, чтобы обеспечить абсолютное использование не более 1,5 ГБ в любое время?

спасибо

@ rancidfishbreath: "ulimit" гарантирует, что java не сможет занять больше указанного объема памяти.Моя цель - обеспечить, чтобы Java никогда не пытался это сделать.

Ответы [ 2 ]

3 голосов
/ 18 августа 2010

top сообщает о 1.6 ГБ, потому что PermSize НА ЛУЧШЕМ максимальном размере кучи.В вашем случае вы устанавливаете MaxPermSize на 512 м, а Xmx на 1024 м.Это составляет 1536м.Как и в других языках, абсолютно точное число не может быть вычислено, если вы точно не знаете, сколько потоков запущено, сколько файловых дескрипторов и т. Д. Размер стека на поток зависит от ОС и версии JDK, в вашем случае его1024 КБ (если это 64-битная машина).Таким образом, если у вас есть 10 потоков, вы используете дополнительно 10240 тыс., Так как стек не выделяется из кучи (Xmx).Большинство приложений, которые ведут себя хорошо, прекрасно работают при установке меньшего стека и MaxPermSize.Попробуйте установить ThreadStackSize равным 128 КБ, и если вы получаете StackOverflowError (т.е. если вы делаете много глубоких рекурсий), вы можете увеличивать его небольшими шагами, пока проблема не исчезнет.

Так что мой ответ, по сути, заключается в том, что вы не можетеуправляйте этим до МБ, сколько будет использовать процесс Java, но вы подходите довольно близко, установив, например, -Xmx1024m -XX: MaxPermSize = 384m и -XX: ThreadStackSize = 128k -XX: + UseCompressedOops.Даже если у вас много потоков, у вас все равно будет много запаса, пока вы не достигнете 1,5 ГБ.UseCompressedOops сообщает виртуальной машине использовать узкие указатели даже при работе на 64-битной JVM, тем самым экономя часть памяти.

1 голос
/ 25 августа 2010

На высоком уровне адресное пространство JVM разделено на три основные части:

  1. пространство ядра: ~ 1 ГБ, также зависит от платформы, Windows больше 1 ГБ
  2. Куча Java: Куча Java, указанная пользователем с помощью -Xmx, -XX:MaxPermSize и т. Д. *
  3. Остальная часть виртуального адресного пространства идет на собственное использование JVM, чтобы приспособить malloc / calloc, выполняемый JVM, стек собственных потоков: поток, соответствующий потокам Java, и добавление собственных потоков JVM для GC и т. Д. *

Таким образом, у вас есть (4 ГБ - пространство ядра 1-1,25 ГБ) ~ 2,75 ГБ для игры, так что вы можете соответственно установить свою кучу java / native. Но, как правило, мы должны оставить как минимум 500 МБ для собственной кучи JVM, в противном случае есть вероятность, что вы получите собственный OOM. Таким образом, мы должны сделать компромисс здесь на основе использования Java кучи вашего приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...