Java-веб-приложение для сбора мусора - PullRequest
2 голосов
/ 25 августа 2010

У меня есть веб-приложение, которое сериализует Java-бин в XML или JSON в соответствии с запросом пользователя.

Я сталкиваюсь с проблемой изгиба ума, когда я немного загружаю его, он быстро использует всю выделенную память и достигает максимальной емкости.Затем я наблюдаю, как полный GC работает очень усердно каждые 20-40 секунд.

Не похоже на проблему утечки памяти ... но я не совсем уверен, как решить эту проблему?

Бин, сериализованный в xml / json, имеет ссылку на другие бины и те,другим.Я использую json-lib и jaxb для сериализации бинов.

yourkit memory profiler говорит мне, что char [] является наиболее потребляющим памятью живым объектом ...

любая оценка приветствуется.

Ответы [ 9 ]

1 голос
/ 25 августа 2010

Почему вы думаете, что у вас есть проблемы? GC - это естественное и нормальное явление. У нас есть клиенты, которые собираются GC каждую секунду (менее 100 мс), и это нормально, пока память восстанавливается.

GCing каждые 20-40 секунд не является проблемой IMO - до тех пор, пока это не займет большой процент от этих 20-40 секунд. Большинство крупных коммерческих JVM стремятся удерживать GC в диапазоне 5-10% времени (то есть 1-4 секунды из этих 20-40 секунд). Публикация большего количества данных в виде журналов GC может помочь, и я бы также предложил инструменты типа GCMV , которые помогут вам визуализировать и получить рекомендации о том, как выглядит ваш профиль GC.

1 голос
/ 25 августа 2010

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

  • Грубый способ узнать, если у васутечка памяти - это запустить ее в течение долгого времени и посмотреть, не упадет ли она с помощью OOME.Или включите ведение журнала GC и посмотрите, будет ли среднее пространство, оставшееся после сбора мусора, постоянно увеличиваться с течением времени.

  • Независимо от того, имеется ли утечка памяти или нет, вы, вероятно, можете повысить производительность (уменьшитьпроцент времени GC) путем увеличения максимального размера кучи.Тот факт, что ваше веб-приложение видит много полных сборок мусора, подсказывает мне, что ему нужно больше кучи.(Это просто решение проблемы, если у вас есть утечка памяти.)

  • Если окажется, что вы не страдаете от утечки памяти, то вам следует узнать, почемуприложение генерирует так много мусора.Это может быть связано с тем, как вы делаете сериализацию XML и JSON.

0 голосов
/ 29 августа 2010

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

В режиме трассировки этот инструмент можно использовать для определения источника выделения памяти .

0 голосов
/ 26 августа 2010

Я бы начал с проверки моего работающего приложения, чтобы увидеть, что создается в куче. HPROF может собрать для вас эту информацию, которую затем можно проанализировать с помощью HAT .

0 голосов
/ 26 августа 2010

Нативный XML API Java действительно «шумный» и, как правило, расточительный с точки зрения ресурсов, что означает, что если ваши запросы и циклы генерации XML / JSON недолговечны, GC придется много чего почистить.

Я отладил очень похожий случай и выяснил, что это трудный путь. Единственный способ хотя бы несколько улучшить ситуацию без серьезных рефакторингов - это неявно вызвать GC с соответствующими флагами ВМ, которые фактически превращают System.gc(); из * 1004. * неоперативный вызов до возможно неоперативный вызов .

0 голосов
/ 25 августа 2010

Для меня это звучит так, будто вы пытаетесь сериализовать рекурсивный объект с помощью какого-то кодера, который не подготовлен к нему. (или, по крайней мере: очень глубокий / почти рекурсивный)

0 голосов
/ 25 августа 2010

Вы должны прикрепить свой комплект и записать распределения (например, каждое 10-е распределение; включая все большие). У них есть пошаговое руководство по диагностике избыточного gc: http://www.yourkit.com/docs/90/help/excessive_gc.jsp

0 голосов
/ 25 августа 2010

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

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

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

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

0 голосов
/ 25 августа 2010

Невозможно диагностировать это без большого количества информации - кода и журналов GC - но я предполагаю, что вы читаете данные в виде больших строк, а затем отбираете маленькие биты с помощью substring ().Когда вы делаете это, строка подстроки создается с использованием того же базового символьного массива, что и родительская строка, и поэтому, пока она жива, будет хранить этот массив в памяти.Это означает, что код, подобный следующему:

String big = a string of one million characters;
String small = big.substring(0, 1);
big = null;

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

small = new String(small);

Но, как я уже сказал, это всего лишь предположение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...