Java-программа работает медленнее после некоторого запуска

У меня есть Java-программа, которая является типичным алгоритмом машинного обучения, обновляя значения для некоторых параметров с помощью некоторых уравнений:

for (int iter=0; iter<1000; iter++) {
    // 1. Create many temporary variables and do some computations                         
    // 2. Update the value for the parameters                    
}

Вычисления параметров обновления довольно сложны, и мне нужно создать много временных объектов, но они не упоминаются вне цикла. Код в цикле загружает процессор и не обращается к диску. Эта программа загружает относительно большой набор обучающих данных, поэтому я выделил 10 ГБ памяти (-Xmx10G) для JVM, что намного больше, чем требуется (пик ~ 6G для «верхней» команды или диспетчера задач окна).

Я протестировал его на нескольких машинах Linux (centos 6, память 24G) и на оконном компьютере (win7, 12G), оба с установленной SUN Hotspot JDK / JRE 1.8. Я не указал другие параметры JVM, кроме -Xmx. Обе машины посвящены моей программе.

На Windows моя программа работает хорошо: каждая итерация использует очень похожее время выполнения. Однако время работы на всех машинах Centos странное.Первоначально он работает правильно, но резко замедляется (примерно в 10 раз медленнее) на 7-й / 8-й итерации, а затем продолжает замедляться на ~ 10% в каждой итерации.

Я подозреваю, что это может быть вызвано сборщиком мусора Java. Поэтому я использую jconsole для мониторинга своей программы. Незначительный сбор данных происходит очень часто на обеих машинах, потому что программа создает много временных переменных в цикле. Кроме того, я использовал команду «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

[Отредактировано] Однако статистика по двум типам машин сильно отличается:

«S1» в окнах быстро перемещается от 0 до 50, в то время как остается на уровне «0,00» в сентосах.«E» в окнах очень быстро изменяется от 0 до 100. Поскольку я печатаю статистику каждую секунду, на снимке экрана не отображается его приращение до 100. Однако на центосах «E» довольно медленно увеличивается до 100, а затем уменьшается до 0 и снова увеличивается.

Кажется, странное поведение моей программы связано с Java GC? Я новичок в мониторинге производительности Java и не имею хорошей идеи оптимизировать настройку параметров GC. У вас есть какие-нибудь предложения? Большое спасибо!

Ответы на вопрос(7)

Ваш ответ на вопрос