Использование памяти Java в Linux - PullRequest
12 голосов
/ 05 сентября 2010

Я использую несколько серверов приложений Java, на которых установлены последние версии Tomcat 6 и Sun 6 от Sun в сочетании с CentOS 5.5 Linux.Каждый сервер запускает несколько экземпляров Tomcat.

Я устанавливаю параметры -Xmx450m -XX: MaxPermSize = 192m, чтобы контролировать размер кучи и permgen.Эти параметры применяются ко всем экземплярам Tomcat на всех серверах приложений Java, в общей сложности около 70 экземпляров Tomcat.

Вот типичное использование памяти одного из этих экземпляров Tomcat, о котором сообщает Psi-probe

Eden           = 13M
Survivor       = 1.5M 
Perm Gen       = 122M 
Code Cache     = 19M 
Old Gen        = 390M 
Total          = 537M

Однако CentOS сообщает об использовании оперативной памяти для этого конкретного процесса на 707M (согласно RSS), что оставляет 170M RAM неучтенным.

Я знаю, что сама JVM и некоторые из ее библиотек зависимости должныбыть загруженным в память, поэтому я решил запустить pmap -d, чтобы узнать их объем памяти.Согласно моим расчетам, это составляет около 17 млн.

Далее идет стек потоков Java, который составляет 320 КБ на поток в 32-битной JVM для Linux.Опять же, я использую Psi-probe, чтобы подсчитать количество потоков в этой конкретной JVM, и всего 129 потоков.Итак, 129 + 320k = 42M

Я читал, что NIO использует память вне кучи, но мы не используем NIO в наших приложениях.

Итак, здесь я вычислил все, чтоприходит в (мое) мнение.И я насчитал только 60 млн. Пропавших без вести 170 млн.

Чего мне не хватает?

Ответы [ 5 ]

3 голосов
/ 08 сентября 2010

Попробуйте использовать инкрементный сборщик мусора, используя параметр командной строки -Xincgc. Он немного более агрессивен во всех усилиях GC и имеет особую счастливую небольшую аномалию: он фактически возвращает часть своей неиспользуемой памяти в ОС, в отличие от настроек по умолчанию и других вариантов GC! Это заставляет JVM потреблять намного меньше памяти, что особенно хорошо, если вы используете несколько JVM на одном компьютере. За счет некоторой производительности - но вы можете не заметить этого. Кажется, что incgc - маленький секрет, потому что никто никогда не поднимал его ... Он был там вечно (даже в 90-х).

2 голосов
/ 05 сентября 2010

Arnar, В процессе инициализации JVM JVM выделит память (mmap или malloc) размера, указанного в -Xmx и MaxPermSize, поэтому в любом случае JVM выделит 450 + 192 = 642 м пространства кучи для приложения в начале процесса JVM , Таким образом, пространство кучи Java для приложения - не 537, а 642 м. Так что теперь, если вы выполните вычисления, это даст вам недостающую память. Надеюсь, это поможет.

1 голос
/ 05 сентября 2010

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

Наконец, 100 МБ стоит около 8 фунтов стерлингов. Вполне возможно, что не стоит тратить на это слишком много времени.

0 голосов
/ 09 сентября 2010

Арнар, JVM также использует все jar-файлы mmap, которые будут использовать NIO и будут вносить вклад в RSS. Я не верю, что это учитывается ни в одном из ваших измерений выше. У вас случайно есть большое количество больших файлов? Если так, то страницы, используемые для них, могут быть вашей недостающей памятью.

0 голосов
/ 07 сентября 2010

Не прямой ответ, но рассматривали ли вы также размещение нескольких сайтов в одном экземпляре Tomcat ?Это может сэкономить вам память за счет дополнительных настроек.

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