2016-11-18 3 views
4

У меня есть приложение (игра), работающее на JVM.java - после медленного приложения GC

Логика обновления игры (которая работает 60 раз/сек) заканчивается примерно на 25%, используемой ее «временной средой» (1/60 с), а затем сбрасывается с оставшихся 75%. Но когда собиратель GC собирается бежать, он поднимается до 75-200% и остается там для остальной части исполнения.

Игра использует около 70 Мб кучи и растет около 1-2 мб/с. Когда GC запускается, он возвращается к 70Mb, поэтому нет истинных утечек памяти. Я попытаюсь снизить это число в будущем, но это не должно быть проблемой в этой области.

Я использую JVM 8 без аргументов или флагов во время выполнения, не знаю, какой GC мне даст.

Я попытался установить кучу на разные размеры, но это не влияет на это явление.

У меня есть две теории относительно того, почему это может быть:

  1. ГХ неумышленно фрагменты моей кучи таким образом, что вызывает кэш громя в цикле обновления. У меня есть логика, которая очень сильно выигрывает от близости данных, когда она проходит через нее и обновляет ее. Может быть, он перетасовывает некоторые данные в старую область, сохраняя некоторые в молодом возрасте (питомник)?

  2. Внезапная обработка GC запускает мою ОС, заставляя ее понять, что мой основной протектор обновления не требует столько ресурсов ЦП, сколько в настоящее время, что снижает его приоритет. (Тем не менее, это явление сохраняется, даже если я пропустить Thread.sleep() отоспаться неиспользованным использованием процессора.

Что вы думаете. Являются ли мои теории правдоподобные, может что-нибудь сделать о них, или же я нужно переключиться на C-язык? Мои знания о GC ограничены.

PS В качестве примечания, как правило, обновление() заканчивается на 75% пост GC. При использовании VSync, когда я получаю цифры, как 200%.

+0

возможно сравнить промахи кеша и связанные с ним статистику с 'perf record'? также, какой JVM? который коллекционер? какие флаги командной строки? – the8472

+0

Спасибо, я добавил некоторую информацию к сообщению. Не уверен, что вы имеете в виду с «pref record», хотя .... – Jake

+0

https://perf.wiki.kernel.org/index.php/Tutorial#Sampling_with_perf_record, и вы должны включить GC-журнал для получения информации о времени паузы (см. Документация JVM о том, как это сделать) – the8472

ответ

0

БОЛЬШЕ НЕ ДЕЙСТВУЕТ:

Я сделала тест и полностью разрушил мою архитектуру. Я это, который был узким местом приложения:

class Physics{ 
    Vec2 centre; 
    Rec hitbox; 
    Vec2 speed; 
    Vec2 acc; 
    ... 

    public void update(){ //critical method 
     centre.doThings(); 
     hitbox.doThings(); 
     etc... 
    } 

} 

И изменили его использование только примитивов:

class Physics{ 
    double centreX,centreY; 
    double x1,x2,y1,y2; 
    double speedX,speedY; 
    double accX,accY; 
    ... 

    public void update(){ //critical method 
     implementation of methods above... 
     etc... 
    } 

} 

Это так, по крайней мере, Java гарантирует, что примитивные методы класса сохраняется в порядок, который они объявлены, под заголовком класса в куче. Хотя ссылки на объекты могут быть адресами на другую сторону кучи.

Это, наряду с уплотняющим GC, дало мне прекрасный импульс, и я благодарен за увеличение количества попаданий в кеш. Он разрушил мою архитектуру, но это цена, которую я готов заплатить.

Игра теперь стабильна на 15%, и теперь я собираюсь отметить свой пост в качестве ответа.

EDIT: Это был просто путаный человек. Вышеуказанное только дало мне небольшое повышение производительности - остальное было вызвано ошибкой в ​​приложении и, следовательно, не оправдывало архитектурные изменения. Однако уплотнение GC помогло немного.

0

Что вы думаете. Являются ли мои теории правдоподобно,

Первая теория правдоподобна, но вторая - нет.

может что-нибудь сделать о них

Вы могли бы улучшить вещи:

  1. Увеличение максимального размера кучи.
  2. Переход к сборщику с низкой паузой.
  3. Оптимизация производительности по результатам профилирования приложения.
  4. Пытается уменьшить скорость вывоза мусора.

или мне нужно переключиться на C или C++?

C и C++ даст вам более предсказуемое поведение, потому что нет ничего, что будет перемещать объекты вокруг. Если у вас есть соответствующие навыки и приложите усилия, вы должны : сможете повысить производительность на C и C++, особенно при выполнении графики/рендеринга. Однако, это большие «если».

+0

Спасибо Стивену, 1. Я попытался увеличить размер кучи, но безуспешно. конечно, он продлевает первое прибытие ГК, но его последствия остаются неизменными. – Jake

+0

2. Я боялся, что мне придется войти и прокормить ГК. – Jake

+0

3. Я не уверен, что получаю ваш смысл – Jake