На Redhat CentOS 6.4 выполняется всего несколько процессов, использующих около 3 ГБ ОЗУ (в системе доступно 12 ГБ). Один из процессов - это сервер WSO2ESB (java), мы запускаем его с такими параметрами:
-Xms2048m -Xmx3072m
Через некоторое время мы получаем исключение OutOfMemory, но процесс java (WSO2ESB) даже не использует свои 3 ГБ. В jconsole вы также можете увидеть, что эти параметры установлены правильно (на данный момент Linux Server имеет около 9 ГБ свободной оперативной памяти)
Linux не дает нам настроенных 3 ГБ ОЗУ?
При точно такой же установке Windows - процесс java может без проблем использовать его 3 ГБ ОЗУ.
Снимок экрана jconsole, показывающий использование памяти кучи только от 0,3 до 1,0 ГБ. В момент исключения OutOfMemory память в куче составляла 0,5 ГБ, но у процесса было бы 3 ГБ для работы, но это не так ...
EDIT: добавлен журнал java-процесса:
java.lang.OutOfMemoryError: unable to create new native thread
EDIT2: добавлен бесплатный вывод -m:
Я решил проблему. wso2esb использовал более 1000 потоков. Но в Linux по умолчанию количество потоков, которые может использовать пользователь, установлено на 1024. Мне пришлось увеличить лимит для моего пользователя, теперь все работает нормально.
Для этого: откройте /etc/security/limits.conf и добавьте следующие две строки для вашего пользователя:
myuser soft nproc 8192
myuser hard nproc 8192
Java имеет несколько поколений кучи, новое и старое постоянное поколение.
Если вы установите действительно высокий Xmx, который используется для кучи, и даже если вы не используете всю кучу, у вас может закончиться память. Обычно это происходит, если у вас заканчивается пространство PermGen.
Постоянное создание кучи используется для хранения пула строк и различных метаданных, необходимых JVM, связанных с классом, методом и другими примитивами Java. Пермское пространство обычно составляет 64 МБ, поэтому, если у вас много классов или огромных строк, вы можете его исчерпать.
Попробуйте увеличить размер перманента, добавив:
-XX:MaxPermSize=256m
к параметрам запуска java.
какой у вас размер сегмента данных для кучи -Xms2048m -Xmx3072m
.
ваш размер сегмента данных должен соответствовать вашему максимальному размеру кучи (который в данном случае составляет 3072 м). Таким образом, размер вашего сегмента данных должен быть установлен как минимум на 3221225472
(в байтах 3 * 1024 * 1024 * 1024 = 3 ГБ)