Попытка вызвать java.lang.OutOfMemoryException - PullRequest
4 голосов
/ 15 марта 2010

Я пытаюсь воспроизвести java.lang.OutOfMemoryException в Jboss4, который получил один из наших клиентов, предположительно, за счет запуска приложений J2EE в течение дней / недель.

Я пытаюсь найти способ, которым веб-приложение выплевывает java.lang.OutOfMemoryException в считанные минуты (вместо дней / недель).

Одна вещь, которая приходит на ум, - это написать сценарий селена, и этот сценарий бомбардирует веб-приложения. Еще одна вещь, которую мы можем сделать, - это уменьшить размер кучи JVM, но мы бы предпочли этого не делать, так как хотим видеть ограничения нашей системы.

Есть предложения?

ps: у меня нет доступа к исходному коду, поскольку мы просто предоставляем услугу хостинга (конечно, я могу декомпилировать файлы классов ...)

Ответы [ 7 ]

1 голос
/ 15 марта 2010

Попробуйте использовать некоторые инструменты профилирования, чтобы исследовать утечку памяти. Также хорошо, чтобы исследовать провалы памяти, которые были взяты после того, как OOM случается и регистрирует. ИМХО: сокращение памяти - это не самый верный способ исследования, потому что вы можете получить проблемы, не связанные с реальным производственным.

1 голос
/ 15 марта 2010

Если у вас нет доступа к исходному коду рассматриваемого приложения J2EE, на ум приходят следующие варианты:

  1. Уменьшите объем оперативной памяти, доступной для JVM. Вы уже определили это и сказали, что не хотите этого делать.

  2. Создайте приложение J2EE (возможно, это просто JSP) и настройте его для работы в той же JVM, что и целевое приложение, и пусть это приложение выделяет смешной объем памяти. Это уменьшит объем памяти, доступной целевому приложению, возможно, так, что оно не будет работать так, как вы пытаетесь форсировать.

0 голосов
/ 15 марта 2010

В дополнение ко всем остальным я должен сказать, что даже если вы сможете воспроизвести ошибку OutOfMemory и выяснить, где она произошла, вы, вероятно, не нашли ничего, что стоит знать.

Проблема в том, что OOM возникает, когда распределение не может быть выполнено. Однако реальная проблема заключается не в этом распределении, а в том, что другие выделения в других частях кода не были отменены (отменены ссылки и сборщик мусора). Неудачное распределение здесь может не иметь никакого отношения к источнику проблемы (без каламбура).

Эта проблема больше в вашем случае, так как могут пройти недели, прежде чем начнутся проблемы, предлагая либо редко используемое приложение, либо ненормальный путь к коду, либо относительно ОГРОМНЫЙ объем памяти по сравнению с тем, что было бы необходимо, если бы код был OK.

Возможно, было бы неплохо спросить, почему этот объем памяти настроен для JBoss, а не что-то другое. Если это рекомендовано поставщиком, чем, возможно, они уже знают об утечке и требуют, чтобы это смягчило последствия ошибки.

Для такого рода ошибок действительно полезно иметь представление о том, в каком пути кода возникает проблема, чтобы вы могли проводить целевые тесты. И протестируйте с помощью профилировщика, чтобы вы могли видеть во время выполнения, какие объекты (списки, карты и т. Д.) Растут без сжатия.

Это дало бы вам возможность декомпилировать правильные классы и посмотреть, что с ними не так. (Закрытие или очистка в блоке try, а не в блоке finally).

В любом случае, удачи. Я думаю, что предпочел бы найти иголку в стоге сена. Когда вы найдете иглу, по крайней мере, знаете, вы нашли ее:)

0 голосов
/ 15 марта 2010

Если у вас нет исходного кода, декомпилируйте его, по крайней мере, если вы считаете, что условия использования позволяют это, и вы живете в свободной стране. Ты можешь использовать: Java Decompiler или JAD .

0 голосов
/ 15 марта 2010

Если вы используете Sun Java 6, вы можете рассмотреть возможность подключения к приложению с помощью jvisualvm в JDK. Это позволит вам выполнить профилирование на месте без необходимости что-либо изменять в вашем сценарии и, возможно, сразу же выявит виновника.

0 голосов
/ 15 марта 2010

Корень проблемы - это, скорее всего, утечка памяти в веб-приложении, которое запускает клиент. Чтобы отследить его, вам нужно запустить приложение с репрезентативной рабочей нагрузкой с включенным профилированием памяти. Сделайте несколько снимков, а затем используйте профилировщик, чтобы сравнить снимки, чтобы увидеть, где объекты протекают. В то время как исходный код был бы идеальным, вы должны быть в состоянии по крайней мере выяснить, где размещаются объекты утечки. Тогда вам нужно отследить причину.

Однако, если ваш клиент не выпустит двоичные файлы, чтобы вы могли запустить систему, идентичную той, которая у него запущена, вы застряли, и вам нужно будет заставить клиента выполнить профилирование и обнаружение утечки самостоятельно .

Кстати - нет особого смысла заставлять веб-приложение выдавать ошибку OutOfMemoryError. Он не скажет вам, почему это происходит, и без понимания «почему» вы ничего не можете с этим поделать.

РЕДАКТИРОВАТЬ

Нет пункта «измерение пределов», если основная причина утечки памяти находится в коде клиента. Предполагая, что вы предоставляете услугу хостинга сервлетов, лучше всего предоставить клиенту инструкции о том, как отлаживать утечки памяти ... и уйти с пути. И если у них есть контракт на поддержку, который требует от вас (по сути) отладки их кода, они должны предоставить вам исходный код для выполнения вашей работы.

0 голосов
/ 15 марта 2010

Делайте оба, но контролируемым образом:

  1. Уменьшите доступную память до абсолютного минимума (используя, например, -Xms1M -Xmx2M, но я боюсь, что ваше приложение даже не загрузится с такими ограничениями)
  2. Делайте контролируемое «ядерное облучение»: делайте сценарии Selenium или каждый из известных рабочих URL-адресов, прежде чем атаковать предполагаемый виновный.
  3. Наконец, дайте волю мощности, которая не должна повышаться: запустите VisualVM и любое другое программное обеспечение для мониторинга, о котором вы можете подумать (выполнение БД - это обычное подозрение).
...