У меня есть Java-программа, которая является типичным алгоритмом машинного обучения, обновляющим значения для некоторых параметров с помощью некоторых уравнений:
for (int iter=0; iter<1000; iter++) {
// 1. Create many temporary variables and do some computations
// 2. Update the value for the parameters
}
Вычисления параметров обновления довольно сложны, и мне приходится создавать много временных объектов, но они не упоминаются вне цикла. Код в цикле имеет интенсивность процессора и не имеет доступа к диску. Эта программа загружает относительно большой учебный набор данных, поэтому я предоставил 10G-памяти (-Xmx10G) для JVM, которая намного больше, чем требуется (пик при ~ 6G с помощью команды "сверху" или диспетчера задач окна).
Я тестировал его на нескольких Linux-машинах (память centos 6, 24G) и оконную машину (win7, 12G), как с установленным SUN Hotspot JDK/JRE 1.8. Я не указывал другие параметры JVM, кроме -Xmx. Обе машины посвящены моей программе.
В окнах моя программа работает хорошо: каждая итерация использует очень похожее время работы. Тем не менее, время работы на всех станциях centos является странным. Он изначально работает правильно, но резко замедляется (~ 10 раз медленнее) на 7-й/8-й итерации, а затем замедляет ~ 10% на каждой итерации.
Я подозреваю, что это может быть вызвано сборщиком мусора Java. Поэтому я использую jconsole для мониторинга моей программы. Незначительный GC происходит очень часто на обеих машинах, потому что программа создает много временных переменных в цикле. Кроме того, я использовал команду jstat -gcutil $pid $1s и зафиксировал статистику:
Centos: https://www.dropbox.com/s/ioz7ai6i1h57eoo/jstat.png?dl=0
Окно: https://www.dropbox.com/s/3uxb7ltbx9kpm9l/jstat-winpng.png?dl=0
[Edited] Однако статистика по двум типам машин сильно различается:
- "S1" на окнах быстро перескакивает от 0 до 50, а при "0,00" - в процентах.
- "E" в окнах очень быстро изменяется от 0 до 100. Когда я печатаю стат каждую секунду, снимок экрана не показывает его прирост до 100. На centos, однако, "E" увеличивается довольно медленно к 100, и затем сводится к 0 и снова увеличивается.
Кажется, странное поведение моей программы связано с Java GC? Я новичок в мониторинге производительности Java и не имею хорошей идеи для оптимизации настройки параметров GC. Есть ли у вас какие-либо предложения? Большое вам спасибо!