У меня есть приложение, в основном создающее новый массив байтов (менее 1K), который хранит некоторые данные через несколько секунд (обычно менее 1 минуты, но некоторые данные хранятся до 1 часа) пишут диск и данные перейдут на мусор. Создается приблизительно 400 пакетов в секунду. Я прочитал некоторые статьи, которые говорят, что не беспокойтесь о GC, особенно быстро созданных и выпущенных частях памяти (на Java 6). GC работает слишком долго, что вызывает некоторые проблемы в моем приложении. Я установил некоторые параметры GC (Bigger XMX и ParalelGC), это уменьшает полное уменьшение времени GC, но пока недостаточно. У меня есть идея 2, Я фокусирую параметры GC или создаю механизм пула памяти массива байтов? Какая из них лучше?Слишком много проблем с мусором на Java
ответ
Я предлагаю вам провести анализ того, почему GC не работает достаточно хорошо для вас. Вы можете использовать jmap
для выгрузки кучи, а затем использовать jhat
или Eclipse Memory Analyser, чтобы узнать, какие объекты в нем живут. Возможно, вы обнаружите, что придерживаетесь ссылок, которые вам больше не нужны.
GC очень умный, и вы действительно можете сделать что-то хуже, пытаясь перехитрить его собственным кодом управления памятью. Попробуйте настроить параметры, и, возможно, вы также можете попробовать новый сборщик мусора G1.
Кроме того, помните, что GC любит недолговечные, неизменные объекты.
Частота выполнения GC зависит от размера объекта, но стоимость (время очистки) больше зависит от количества объектов. Я подозреваю, что длинные живые массивы копируются между пространствами до тех пор, пока они не окажутся в старом пространстве и, наконец, отброшены. Очистка старого поколения относительно дорога.
Предлагаю вам попробовать использовать ByteBuffer для хранения данных. Они похожи на байты [], но имеют переменный размер и могут быть немного более эффективными, если вы можете использовать прямые байтовые буферы с NIO. Предварительное выделение ваших буферов может быть более эффективным для предопределения ваших буферов. (хотя может тратить виртуальную память)
BTW: Прямые байтовые буферы используют небольшое количество кучи, поскольку они используют память в пространстве «C».
- Используйте профайлер для идентификации фрагмент кода
- Попробуйте с WeakReferences.
- Предложите GC Algo к VM
-Xgc: parallel
- Установите большой ворох и общий MEM
-XX:+UseISM -XX:+AggressiveHeap
- ниже для сбора мусора.
-XX:SurvivorRatio 8
Почему вы увеличиваете Xmx? Если вы на самом деле не нуждаетесь в памяти, она обычно * замедляет ваше приложение (потому что для ненужного мусора больше места, и GC придется больше работать). В общем, вы должны предоставить «достаточно» памяти. Не более! –
Увеличение -mx может уменьшить частоту выполнения GC, но увеличивать, сколько времени они берут, когда делают. –
В качестве альтернативы, возможно, вы могли бы выгрузить часть обработки в другой поток, что позволит вам использовать больше доступной пропускной способности процессора (при условии, что у вас многоядерный процессор)? – msandiford