Сборка мусора Java и атомарные события/остановка gc приостанавливает работу, прерывая последовательность функциональных вызовов

У меня есть сложное большое многопоточное приложение, в которое я добавляю новую функциональность.

Я добавил вызов к специализированному оборудованию (через JNI lib, предоставленную поставщиком). Однако перед вызовом этой (очень быстрой) функции предварительно выполняется некоторая работа по заполнению структуры данных, отправленной ей.

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

Есть ли способ сказать «синхронизировать для GC» эти операции, чтобы они не задерживались во время остановки мирового GC?

Использование 64-битного JDK 1.7 на RHL5.5

Спасибо


person easytiger    schedule 26.03.2013    source источник
comment
Просто чтобы уточнить, вы видите проблемы во время полной очистки GC или также при выполнении незначительной очистки GC?   -  person JustDanyul    schedule 26.03.2013
comment
Короткий ответ, нет. Если вы сталкиваетесь с остановкой мира gc, то регулярно что-то не так. Какие настройки gc вы используете?   -  person Boris the Spider    schedule 26.03.2013
comment
JustSanyul, я полагаю, что во время полного возникают большие проблемы (последовательность операций может занять много-много миллисекунд, когда она должна занимать ‹5 микросекунд. действительно, чтобы написать операцию самостоятельно, требуется 1,3 микросекунды)   -  person easytiger    schedule 26.03.2013
comment
Если у вас есть требования к реальному времени, возможно, вам следует рассмотреть возможность использования платформы реального времени.   -  person NPE    schedule 26.03.2013
comment
Какой тип ГХ вы используете? Вы пробовали G1[Garbage First]?   -  person Jabir    schedule 26.03.2013
comment
stackoverflow.com/ вопросы/4051966/   -  person andersoj    schedule 26.03.2013


Ответы (4)


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

Во-первых, попробуйте проанализировать, какие обстоятельства запускают эти полные зачистки, у вас вообще мало места в куче? И если да, то почему у вас часто заканчивается куча (есть ли где-то потенциальная утечка?)

Также при малой (более быстрой) сборке мусора объекты перемещаются из молодых поколений (эдем и выживший 1) в выживший 2. Если не помещается в выживший 2, они будут перемещены в постоянные, если нет достаточно места в штате, вы вызываете полную зачистку. Итак, если ваши молодые поколения большие и у вас есть определенное количество долго работающих объектов, это может вызвать проблемы.

В конце концов, вы должны проанализировать это. Профилируйте свое приложение и определите, когда и почему вы видите полные сборки мусора, а затем настройте свое приложение, чтобы сделать их менее частыми или потенциально гарантировать, что они настолько редки, что вы можете «контролировать», когда они происходят.

person JustDanyul    schedule 26.03.2013

Поведение сборщика мусора не является детерминированным, поэтому вы не можете обеспечить синхронизацию.

Мне на ум приходят три варианта:

  • Вы создаете много объектов для заполнения структуры данных для каждого вызова? Возможно, вы можете повторно использовать их, чтобы избежать заполнения кучи и автоматических вызовов GC.
  • Запустите виртуальную машину с предварительно выделенной памятью, чтобы распределить вызовы gc.
  • Вызовите System.gc() самостоятельно, если это не вредно для вашего приложения. Этот вызов является всего лишь предложением (JVM может его игнорировать), но я попробую.

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

person Pablo Lozano    schedule 26.03.2013
comment
Спасибо, Пабло. Нет, сам вызов повторно использует один и тот же байтовый буфер на протяжении всего жизненного цикла приложения. - person easytiger; 26.03.2013
comment
@pablo Я думаю, ты имеешь в виду, что не можешь гарантировать..., не можешь? - person sharakan; 26.03.2013
comment
Боюсь, моя точка зрения заключалась в том, что это большое существующее устаревшее приложение. Непрактично говорить «выбросить все это». Мой вопрос был о проблеме GC для некоторых критических разделов. - person easytiger; 26.03.2013

Просто для полноты вы также можете использовать JVM, реализующую Real-time Java (RTSJ).

В JVM реального времени вы можете выполнить свою срочную задачу в потоке, который не будет прерван каким-либо GC мероприятия. К сожалению, в настоящее время доступно не так много RT JVM.

person Aleš    schedule 26.03.2013

Если вы создаете новую задачу, зависящую от времени, и не можете исправить поведение GC JVM с помощью задачи, то есть еще один вариант: вы можете переместить задачу в отдельную JVM.

Межпроцессное/машинное взаимодействие будет означать более высокую минимальную производительность, но в отдельном экземпляре JVM, который выполняет ваше взаимодействие с JNI, вы можете настроить GC с большей свободой, чем в родительском процессе, и тем самым получить больше контроля над изменчивостью.

person sharakan    schedule 27.03.2013