У меня есть несколько дампов кучи, которые я анализирую после того, как JVM выдала OutOfMemory
исключений. Я использую Hotspot JDK 1.7 (64-разрядная версия) на платформе Windows 2008R2. Сервер приложений представляет собой JBoss 4.2.1GA, запускаемый с помощью Tanuki Java Service Wrapper. а>.
Он запускается со следующими аргументами:
wrapper.java.additional.2=-XX:MaxPermSize=256m
wrapper.java.initmemory=1498
wrapper.java.maxmemory=3000
wrapper.java.additional.19=-XX:+HeapDumpOnOutOfMemoryError
что переводится как:
-Xms1498m -Xmx3000m -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError
Есть и другие параметры конфигурации GC и JMX.
Моя проблема заключается в том, что когда я анализирую дамп кучи, созданный из-за OutOfMemoryException
, с помощью Eclipse Memory Analyzer, неизменно, MAT показывает размер кучи 2,3 ГБ или 2,4 ГБ. Я уже включил параметр в MAT на Keep Unreachable Objects
, поэтому я не верю, что MAT урезает кучу.
java.lang.RuntimeException: java.lang.OutOfMemoryError: GC overhead limit exceeded
or
java.lang.OutOfMemoryError: Java heap space
Резюме в МАТ:
Size: 2.3 GB Classes: 21.7k Objects: 47.6m Class Loader: 5.2k
Мои фактические размеры файлов кучи составляют примерно 3300 КБ, поэтому они соответствуют моей настройке максимального размера кучи 3000 м.
Так где же недостающие 500-600М памяти в МАТ? Почему MAT показывает размер моей кучи только как 2,4 ГБ?
Другие сообщения на SO, как правило, указывают на то, что JVM выполняет некоторый GC перед сбросом кучи, но если недостающие 500M связаны с GC, почему он вообще выбрасывает OOM? Если GC действительно может очистить 500M (или почти 25% моей кучи), действительно ли JVM не хватает памяти?
Есть ли способы настроить дампы кучи, чтобы я мог получить полную/полную картину кучи (включая недостающие 500 МБ)?
Если нет, то я действительно изо всех сил пытаюсь понять, как/почему я вообще сталкиваюсь с этими OOM.
По чьей-то просьбе я прикрепляю вывод jstat -gc <PID> 1000
из работающего узла: http://pastebin.com/07KMG1tr а>.