
На Redhat CentOS 6.4 запущено всего несколько процессов, использующих около 3 ГБ оперативной памяти (в системе доступно 12 ГБ). Один из процессов — это WSO2ESB Server (java), мы запускаем его с такими параметрами:
-Xms2048m -Xmx3072m
Через некоторое время мы получаем исключение OutOfMemory Exception, нопроцесс Java (WSO2ESB) даже не использует свои 3 ГБ. В jconsole вы также можете увидеть, что эти параметры установлены правильно (на данный момент на сервере Linux имеется около 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: добавлен вывод free -m:
решение1
Я решил проблему. wso2esb использовал более 1000 потоков. Но в Linux количество потоков по умолчанию, которое может использовать пользователь, установлено на 1024. Мне пришлось увеличить лимит для своего пользователя, теперь все работает нормально.
Для этого откройте /etc/security/limits.conf и добавьте следующие две строки для вашего пользователя:
myuser soft nproc 8192
myuser hard nproc 8192
решение2
В Java есть несколько поколений пространства кучи, новое, старое постоянное поколение.
Если вы установите очень высокий Xmx, который используется для кучи, и даже если вы не используете всю кучу, вы можете исчерпать память. Это обычно происходит, если вы исчерпали пространство PermGen.
Постоянное создание кучи используется для хранения пула строк и различных метаданных, требуемых JVM, связанных с классом, методом и другими примитивами Java. Постоянное пространство обычно составляет 64 МБ, поэтому если у вас много классов или огромных строк, вы можете его исчерпать.
Попробуйте увеличить размер пермгена, добавив:
-XX:MaxPermSize=256m
в параметры запуска Java.
решение3
каков размер сегмента данных для кучи -Xms2048m -Xmx3072m
?
Размер вашего сегмента данных должен соответствовать максимальному размеру кучи (в данном случае это 3072 м). Поэтому размер вашего сегмента данных должен быть установлен по крайней мере 3221225472
(в байтах 3*1024*1024*1024 = 3 ГБ)