Почему память никогда не освобождается в моем приложении Tomcat JRuby?

У меня есть приложение JRuby on Rails, которое работает внутри Tomcat (Warble). Он использует мост Java для подключения к серверу приложений Progress (OpenEdge) ... Когда я отслеживаю память, она только увеличивается.

  • Томкэт 7.0
  • JRuby 1.6.7.2 (Ruby-1.9.2-p312)
  • JVM 1.7.0.25
  • Рельсы 3.2.7
  • jruby-стойка 1.1.7
  • славка 1.3.6

Какой лучший способ добраться до сути проблемы здесь? Я предполагаю, что это могут быть либо объекты JRuby, которые не очищены, либо что-то в Java-мосте или сборщике мусора, который не выполняет свою работу...

Даже если я позволю процессу работать в течение получаса, память не снижается ...

  • Есть ли способ узнать, какие Объекты живы?
  • Существуют ли простые в использовании бесплатные инструменты, с помощью которых я могу получить больше информации о том, кто использует всю память?

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

РЕДАКТИРОВАТЬ: На самом деле я вижу, что Tomcat просто использует всю память, которую он может максимально использовать (максимальный пул памяти). И никогда не выпускает. Может быть, это просто нормальное поведение ... Например, я установил максимум на 256 МБ, а в диспетчере задач память остается около 256 МБ.

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

Когда я создаю дамп кучи и позволяю eclipse анализировать его с помощью анализатора памяти Eclipse, это отчет, который я получаю. Я думаю, что это нормально, поскольку инструмент, вероятно, не ожидает всей истории JRuby...

Подозрение на проблему 1

6.458 экземпляров «org.jruby.RubyClass», загруженных «org.apache.catalina.loader.WebappClassLoader @ 0x700ec6988», занимают 56.969.616 (31,78%) байт.

Ключевые слова org.apache.catalina.loader.WebappClassLoader @ 0x700ec6988 org.jruby.RubyClass

Подозреваемый в проблеме 2

10 597 экземпляров «org.jruby.internal.runtime.methods.DefaultMethod», загруженных «org.apache.catalina.loader.WebappClassLoader @ 0x700ec6988», занимают 22 182 112 (12,37%) байт.

Ключевые слова org.jruby.internal.runtime.methods.DefaultMethod org.apache.catalina.loader.WebappClassLoader @ 0x700ec6988

Подозрение на проблему 3

3.144 экземпляра "org.jruby.RubyModule", загруженные "org.apache.catalina.loader.WebappClassLoader @ 0x700ec6988", занимают 21.226.816 (11,84%) байт.

Ключевые слова org.apache.catalina.loader.WebappClassLoader @ 0x700ec6988 org.jruby.RubyModule

Подозреваемый в проблеме 4

8.888 экземпляров «org.jruby.MetaClass», загруженных «org.apache.catalina.loader.WebappClassLoader @ 0x700ec6988», занимают 18.563.784 (10,35%) байт.

Ключевые слова org.jruby.MetaClass org.apache.catalina.loader.WebappClassLoader @ 0x700ec6988


person Lieven Cardoen    schedule 26.06.2013    source источник
comment
В чем конкретно проблема? Вам не хватает памяти? Какая версия JRuby? Какая версия рельсов? И т. д. Нет ни одного из них 3.7.   -  person Dave Newton    schedule 26.06.2013
comment
Конкретная проблема заключалась в следующем: ERROR Java Heap Space. Больше информации в логах не было.   -  person Lieven Cardoen    schedule 27.06.2013
comment
Я обновлю свой вопрос со всей конкретной версией.   -  person Lieven Cardoen    schedule 27.06.2013
comment
Я получил информацию о памяти/процессоре/потоках от Java VisualVM. Мне все еще любопытно узнать, являются ли подозреваемые проблемы от Eclipse Memory Analyzer действительно проблемой.   -  person Lieven Cardoen    schedule 27.06.2013
comment
@LievenCardoen, вы проверяли, какая часть пространства кучи поколений (Eden, Tenured или PermGen) увеличивается и не освобождается? Если это PermGen, то тут уж ничего не поделаешь.   -  person Santosh    schedule 05.07.2013
comment
@Santosh Это действительно PermGen, и я думаю, вы правы, что с этим мало что можно поделать. Спасибо.   -  person Lieven Cardoen    schedule 01.08.2013


Ответы (2)


Прежде всего: 256M Heap Space не так уж много для Java-приложений, особенно если задействован полноценный контейнер сервлетов/сервер приложений и (вероятно) множество библиотек.

Java обычно не возвращает память операционной системе — после выделения памяти считается, что она принадлежит JVM. Я полагаю, что могут быть некоторые реализации управления памятью, которые возвращают память, но я никогда их не видел. Моя типичная рекомендация в производственных средах - в любом случае иметь -Xmx равно -Xms (выделить всю память, которую вы хотите, чтобы JVM могла выделить немедленно)

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

Увеличьте выделение памяти для вашей JVM и отслеживайте использование памяти и сборку мусора, чтобы исключить б) - если вы можете с уверенностью сказать, что у вашего приложения достаточно памяти для своих нужд, ищите а) и найдите основную причину утечки памяти. Лучше всего использовать для этого профилировщик, но с 256 МБ памяти велика вероятность, что вам просто не хватит памяти.

person Olaf Kock    schedule 05.07.2013

Это сильно попахивает утечкой памяти. Не красивое зрелище.

Если кода не много, сначала проверьте на глаз, что вы закрываете соединения и потоки и все объекты, у которых есть метод close. Если эта проблема возникла недавно, взгляните на последний измененный код.

Еще я бы попробовал проверить код с помощью некоторого инструмента.

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

Я не рекомендую вам проверять объекты в памяти, так как это медленный и болезненный процесс.

person Terafor    schedule 01.07.2013