У меня есть приложение, в основном создающее новый массив байтов (менее 1 КБ), сохраняющее некоторые данные через несколько секунд (обычно менее 1 минуты, но некоторые данные хранятся до 1 часа), записывающие на диск, и данные будут отправлены в мусор. Создано около 400 пакетов в секунду. Я читал некоторые статьи, в которых говорится, что не беспокойтесь о том, что GC особенно быстро создает и освобождает части памяти (на Java 6). GC работает слишком долго, что вызывает некоторые проблемы с моим приложением. Я установил некоторые параметры GC (Bigger XMX и ParalelGC), это уменьшило время полного GC, но этого недостаточно. У меня есть 2 идеи: я фокусирую параметры GC или создаю механизм пула памяти байтового массива? Какой из них лучше?
Проблема слишком большого количества мусора в Java
Ответы (3)
Я предлагаю вам проанализировать, почему GC работает недостаточно хорошо для вас. Вы можете использовать jmap
для вывода кучи а затем используйте jhat
или Анализатор памяти Eclipse, чтобы увидеть, какие объекты в нем живут. Вы можете обнаружить, что держитесь за ссылки, которые вам больше не нужны.
Сборщик мусора очень умен, и вы можете усугубить ситуацию, пытаясь перехитрить его с помощью собственного кода управления памятью. Попробуйте настроить параметры и, возможно, вы также сможете попробовать новый сборщик мусора G1.
Также помните, что сборщик мусора любит недолговечные неизменяемые объекты.
Частота выполнения GC зависит от размера объекта, но стоимость (время очистки) больше зависит от количества объектов. Я подозреваю, что долгоживущие массивы копируются между пространствами, пока не окажутся в старом пространстве и, наконец, не будут удалены. Очистка старого поколения относительно дорогая.
Я предлагаю вам попробовать использовать ByteBuffer для хранения данных. Они похожи на byte[], но имеют переменный размер и могут быть немного более эффективными, если вы можете использовать прямые байтовые буферы с NIO. Предварительное выделение ваших буферов может быть более эффективным, чем предварительное выделение ваших буферов. (хотя может тратить виртуальную память)
Кстати: прямые буферы байтов используют мало места в куче, поскольку они используют память в пространстве «C».
- Используйте профилировщик для идентификации фрагмента кода
- Попробуйте через WeakReferences.
- Предложить алгоритм GC для виртуальной машины
-Xgc: parallel
- Установите большую кучу и разделяемый мем
-XX:+UseISM -XX:+AggressiveHeap
- установить ниже для сбора мусора.
-XX:SurvivorRatio 8
- Это может помочь http://download.oracle.com/docs/cd/E12840_01/wls/docs103/perform/JVMTuning.html#wp1130305