OutOfMemoryError во время длинного пакета на Grails / Tomcat - PullRequest
0 голосов
/ 15 ноября 2010

Я запускаю длинную партию в своем приложении Grails. Служба связывается с веб-службой и загружает XML, который хранится локально в приложении Grails (в БД). Загруженные объекты довольно большие и сложные, и приложение обрабатывает их и создает объекты локального домена. Я использую Grails 1.2.2 , потому что я не мог обновить свое приложение до самой последней версии (я потратил на это несколько часов, а затем добавил губку).

Это в основном длинный цикл с небольшим количеством общей информации между итерациями.

Это что-то вроде:

while( stillObjectsToDo ){
   def bigObj = myservice.fetchXML
   def localInstance = myservice.processObj( bigObj )
   localInstance.saveEverythingToDB
   clearGORM
}

Я запускаю приложение на Tomcat , которое было настроено для увеличения размера кучи. Когда я обрабатываю один объект, у меня никогда не было проблем. Но когда я запускаю полную партию (около 1500 больших объектов), я всегда получаю:

codehaus.groovy.grails.web.servlet.mvc.exceptions.ControllerExecutionException: Executing action [runSampleBatch] of controller [semanticopenstreetmap.EngineController]  caused exception: java.lang.OutOfMemoryError: Java heap space
 at java.lang.Thread.run(Thread.java:619)
Caused by: org.codehaus.groovy.runtime.InvokerInvocationException: java.lang.OutOfMemoryError: Java heap space
 ... 1 more
Caused by: java.lang.OutOfMemoryError: Java heap space
 at java.util.Arrays.copyOf(Arrays.java:2882)

Кажется, какая-то утечка памяти, но я не могу ее найти. Это действительно странно, потому что объекты хранятся в БД и больше не используются в процедуре, поэтому их просто нужно очистить.

Я попробовал следующие решения, чтобы избежать проблемы без удачи:

  • Очистить Сеанс гибернации после очистки каждого объекта в каждой итерации
  • Звоните сборщик мусора каждые 5-6 минут.
  • обнулить предыдущий объект вручную в конце цикла (вероятно, бесполезно).

Ничего из этого не работало эффективно. Использование памяти продолжает расти. Я использовал Virtual VM, и я получил этот график: http://img12.imageshack.us/img12/5660/memoryleak.png И классы: http://img263.imageshack.us/img263/331/memoryleakclasses.png

Как я могу найти и устранить эту утечку памяти?

EDIT: имеет ли смысл запускать каждый объект в отдельном потоке ? Утечка памяти происходит в процессе http-0-x, как я могу проверить этот объект?

Есть подсказки?

Спасибо!

Mulone

Ответы [ 4 ]

1 голос
/ 16 ноября 2010

В GORM есть известная утечка памяти, которую нельзя устранить, очистив сеанс.Берт Беквит написал это здесь .По сути, решение заключается в том, чтобы позвонить DomainClassGrailsPlugin.PROPERTY_INSTANCE_MAP.get().clear()

1 голос
/ 15 ноября 2010

Вам необходимо прикрепить внешний профилировщик к вашему приложению. Вот хороший.

https://visualvm.dev.java.net/

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

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

1 голос
/ 15 ноября 2010

Это потенциальная область исследования: Устранение неполадок Grails / утечек памяти в Groovy?

1 голос
/ 15 ноября 2010

Я бы использовал Visual VM, чтобы присоединиться к процессу и посмотреть, что происходит с памятью.

Мне интересно, заполняют ли динамически сгенерированные прокси ваше пространство для перманента. Visual VM предоставит вам подтверждение того, что это правда.

...