2011-01-17 3 views
3

У меня есть приложение, в основном создающее новый массив байтов (менее 1K), который хранит некоторые данные через несколько секунд (обычно менее 1 минуты, но некоторые данные хранятся до 1 часа) пишут диск и данные перейдут на мусор. Создается приблизительно 400 пакетов в секунду. Я прочитал некоторые статьи, которые говорят, что не беспокойтесь о GC, особенно быстро созданных и выпущенных частях памяти (на Java 6). GC работает слишком долго, что вызывает некоторые проблемы в моем приложении. Я установил некоторые параметры GC (Bigger XMX и ParalelGC), это уменьшает полное уменьшение времени GC, но пока недостаточно. У меня есть идея 2, Я фокусирую параметры GC или создаю механизм пула памяти массива байтов? Какая из них лучше?Слишком много проблем с мусором на Java

+3

Почему вы увеличиваете Xmx? Если вы на самом деле не нуждаетесь в памяти, она обычно * замедляет ваше приложение (потому что для ненужного мусора больше места, и GC придется больше работать). В общем, вы должны предоставить «достаточно» памяти. Не более! –

+0

Увеличение -mx может уменьшить частоту выполнения GC, но увеличивать, сколько времени они берут, когда делают. –

+0

В качестве альтернативы, возможно, вы могли бы выгрузить часть обработки в другой поток, что позволит вам использовать больше доступной пропускной способности процессора (при условии, что у вас многоядерный процессор)? – msandiford

ответ

0

Я предлагаю вам провести анализ того, почему GC не работает достаточно хорошо для вас. Вы можете использовать jmap для выгрузки кучи, а затем использовать jhat или Eclipse Memory Analyser, чтобы узнать, какие объекты в нем живут. Возможно, вы обнаружите, что придерживаетесь ссылок, которые вам больше не нужны.

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

Кроме того, помните, что GC любит недолговечные, неизменные объекты.

4

Частота выполнения GC зависит от размера объекта, но стоимость (время очистки) больше зависит от количества объектов. Я подозреваю, что длинные живые массивы копируются между пространствами до тех пор, пока они не окажутся в старом пространстве и, наконец, отброшены. Очистка старого поколения относительно дорога.

Предлагаю вам попробовать использовать ByteBuffer для хранения данных. Они похожи на байты [], но имеют переменный размер и могут быть немного более эффективными, если вы можете использовать прямые байтовые буферы с NIO. Предварительное выделение ваших буферов может быть более эффективным для предопределения ваших буферов. (хотя может тратить виртуальную память)

BTW: Прямые байтовые буферы используют небольшое количество кучи, поскольку они используют память в пространстве «C».

0
  1. Используйте профайлер для идентификации фрагмент кода
  2. Попробуйте с WeakReferences.
  3. Предложите GC Algo к VM
-Xgc: parallel 
  1. Установите большой ворох и общий MEM
-XX:+UseISM -XX:+AggressiveHeap 
  1. ниже для сбора мусора.

-XX:SurvivorRatio 8

  1. Это может помочь http://download.oracle.com/docs/cd/E12840_01/wls/docs103/perform/JVMTuning.html#wp1130305