Как устранить ошибку "Недостаточно памяти" в производственной системе
Мы используем JBoss_4_0_4_GA с JDK 1.5.0 (без обновлений) в Windows
Сервер JBoss работает в Wrapper (версия 3.2.3) http://wrapper.tanukisoftware.org/.
Поскольку JVM очень старая, я даже не могу использовать опцию -XX:+HeapDumpOnOutOfMemoryError на JVM.
Каковы мои варианты, чтобы выяснить проблему?
Как обычно, исключение "Недостаточно памяти" происходит в разных частях приложения.
Я не могу сразу обновить JVM.
The current VM settings
Java Additional Parameters
wrapper.java.additional.1=-Xms512m
wrapper.java.additional.2=-Xmx1024m
wrapper.java.additional.3=-Dsun.rmi.dgc.client.gcInterval=3600000
wrapper.java.additional.4=-Dsun.rmi.dgc.server.gcInterval=3600000
wrapper.java.additional.5=-Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser
wrapper.java.additional.6=-Djava.endorsed.dirs=D:/jboss-4.0.4.GA/lib/endorsed
Фрагменты исключения
ИНФО | JVM 1 | 2012/05/31 11:25:03 | 11:25:03,502 ОШИБКА [SOAPFaultExceptionHelper] Исключение запроса SOAP INFO | JVM 1 | 2012/05/31 11:25:03 | java.rmi.RemoteException: java.lang.OutOfMemoryError: пространство кучи Java; Вложенное исключение: INFO | JVM 1 | 2012/05/31 11:25:03 | java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: пространство кучи Java
ИНФО | JVM 1 | 2012/05/31 11:25:03 | Вызывается: java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: Пространство кучи Java INFO | JVM 1 | 2012/05/31 11:25:03 | at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:205) INFO | JVM 1 | 2012/05/31 11:25:03 | в java.util.concurrent.FutureTask.get(FutureTask.java:80)
2 ответа
Вы можете попробовать сделать дамп памяти с помощью jmap (в упомянутых вами тегах java 5
так что это должно быть возможно). Делайте несколько дампов, когда сервер все еще работает (например, каждый час или около того).
Затем проанализируйте их в Eclipse MAT. Поиск объектов или коллекций объектов, которые растут на каждой свалке. Скорее всего, это будет ваша утечка памяти.
Я вижу два варианта, каждый из которых имеет свои плюсы и минусы:
Установите агент профилировщика и подключите профилировщик к вашему приложению. Это, конечно, оказывает серьезное влияние на производительность, которое может быть неприемлемым в вашей производственной среде. Но это позволит вам контролировать приложение и выполнять дамп памяти, когда пространство кучи почти заполнено.
Воспроизведите свою производственную среду в другом месте, а также используйте профилировщик. Если ваши проблемы появляются только при больших нагрузках, вам, возможно, придется создать нагрузочные тесты, чтобы достичь OOME.
Использование профилировщика - ваш лучший шанс обнаружить утечки памяти.
В противном случае вы всегда можете попробовать выполнить статический анализ кода, используя PMD и Findbugs (среди других инструментов статического анализа), которые могут обнаружить некоторые ошибки.