Как освободить память? - PullRequest
       18

Как освободить память?

17 голосов
/ 24 марта 2010

В течение некоторого времени мы сталкивались с ошибками нехватки памяти на нашем сервере приложений. Мы видим, как размер используемой кучи постепенно увеличивается, пока, наконец, не достигнет размера доступной кучи. Это происходит каждые 3 недели, после чего требуется перезапуск сервера, чтобы это исправить. После анализа дампов кучи мы обнаруживаем, что проблема заключается в объектах, используемых в JSP.

Могут ли объекты JSP быть реальной причиной проблем с памятью в Appserver? Как освободить объекты JSP (объекты, экземпляры которых создаются с использованием usebean или других тегов)?

У нас есть кластерный сервер приложений Websphere с 2 узлами и IHS.

РЕДАКТИРОВАТЬ: Результаты, представленные выше, основаны на анализе журнала heap-dump и nativestderr, приведенном ниже с использованием помощника службы поддержки IBM

nativestd Ошибка анализа журнала:

альтернативный текст http://saregos.com/wp-content/uploads/2010/03/chart.jpg

Анализ дампа кучи:

! [Альтернативный текст] [2]

Анализ дампа кучи, показывающий непосредственные доминаторы (на 2 ступени выше возможного входа на изображении выше)

! [Альтернативный текст] [3]

Последнее изображение показывает, что непосредственные доминанты на самом деле являются объектами, используемыми в JSP.

РЕДАКТИРОВАТЬ2: Более подробная информация доступна на http://saregos.com/?p=43

Ответы [ 6 ]

8 голосов
/ 30 марта 2010

Я бы сначала прикрепил инструмент профиля, чтобы сказать вам, что это за «объекты», которые занимают всю память.

Eclipse имеет TPTP, или есть JProfiler или JProbe.

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

Затем найдите в базе кода, кто их создает.

Возможно, у вас есть объект кэша или дерева / карты с элементами, и вы реализовали только метод equals () для этих объектов, и вам нужно реализовать hashcode (). Это может привести к тому, что карта / кеш / дерево будет становиться все больше и больше, пока оно не упадет. Это всего лишь предположение.

JProfiler будет моим первым звонком

В Javaworld есть скриншот того, что находится в памяти ...

альтернативный текст http://www.javaworld.com/javaworld/jw-08-2003/images/jw-0822-profiler16.gif

И снимок экрана с созданием и очисткой кучи объектов (отсюда и край пилы)

альтернативный текст http://www.javaworld.com/javaworld/jw-08-2003/images/jw-0822-profiler19.gif

ОБНОВЛЕНИЕ ********************************************** ***

Хорошо, я бы посмотрел на ...

http://www -01.ibm.com / поддержка / docview.wss? UID = swg1PK38940

Использование кучи увеличивается со временем, что приводит к OutOfMemory состояние. Анализ heapdump показывает, что следующее объекты занимают все больше места:

40 543 128 [304] 47 класс

ком / IBM / wsspi / rasdiag / DiagnosticConfigHome 40,539,056 [56] 2 Java / утилита / Hashtable 0xa8089170 40 539 000 [2 064] 511 массив java / util / Hashtable $ Entry 6,300,888 [40] 3 java / util / Hashtable $ HashtableCacheHashEntry

7 голосов
/ 29 марта 2010

Запуск сборки мусора вручную не решит вашу проблему - он не освободит ресурсы, которые все еще используются.

Вы должны использовать инструмент профилирования (например, jProfiler), чтобы найти утечки. Вы, вероятно, используете код, который хранит ссылки в списках или картах, которые не выпускаются во время выполнения - вероятно, статические ссылки.

2 голосов
/ 31 марта 2010

Предлагаю прочитать Эффективная Java, глава 2 . После этого, вместе с профилировщиком, вы сможете определить места, где ваше приложение вызывает утечки памяти.

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

  • неправильно написанный код - решение состоит в том, чтобы написать его правильно, чтобы он не потреблял больше, чем необходимо - здесь поможет эффективная Java.
  • приложению просто нужно столько памяти. Затем вы должны увеличить память виртуальной машины, используя Xmx, Xms, XX:MaxHeapSize, ...
2 голосов
/ 30 марта 2010

Если вы работаете под JVM от Sun 6, настоятельно рекомендуется использовать программу Jvisualvm в JDK, чтобы получить начальный обзор того, что на самом деле происходит внутри программы. Сравнение снимков действительно полезно, чтобы помочь вам понять, какие объекты проскальзывают.

Если Sun 6 JVM не подходит, то выясните, какие инструменты профилирования у вас есть. Испытания могут сделать вас очень далеко.

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

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

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

Некоторые подсказки, которые могут помочь:

  • Проверьте сферу ваших бобов. не являются Вы, например. что-то хранит пользователь или конкретный запрос в "приложение" сфера (по ошибке)?
  • Проверьте настройки времени ожидания веб-сессии в вашем веб-приложении и Настройки сервера приложений.
  • Вы упомянули, что потребление кучи постепенно увеличивается. Если это действительно так, попробуй посмотреть на сколько размер кучи растет с различными пользовательскими сценариями: Возьмите кучу, запустите тест, пусть тайм-аут данных сеанса, получить другой дамп, сравните два. Которые могут дать вам некоторое представление, откуда берутся объекты в куче
  • Проверьте ваши бины на наличие явных утечек памяти, наверняка:)

РЕДАКТИРОВАТЬ: Проверка на неизданные статические ресурсы, о которых упоминает Даниэль, - еще одна полезная вещь:)

0 голосов
/ 04 апреля 2010

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

...