После долгих поисков лучшее объяснение, которое я нашел, было найдено на веб-сайте настройки производительности Java в Вопросе месяца: 1.4.1 Алгоритмы сборки мусора, 29 января 2003 г.
Алгоритмы сборки мусора молодого поколения
(Оригинал) копирование коллектор (по умолчанию включено). Когда срабатывает этот сборщик, все потоки приложения останавливаются, и копирование коллекции продолжается с использованием одного потока (что означает только один ЦП, даже если на многопроцессорной машине). Это известно как коллекция stop-the-world, потому что в основном JVM приостанавливает все остальное, пока коллекция не будет завершена.
Параллельное копирование коллектора (Включено с помощью -XX: + UseParNewGC). Подобно оригинальному коллекционеру копий, этот коллекционер остановит мир. Однако этот сборщик распараллеливает коллекцию копий по нескольким потокам, что более эффективно, чем исходный однопоточный сборщик копирования для многопроцессорных машин (но не для однопроцессорных машин). Этот алгоритм потенциально ускоряет сбор данных молодого поколения в размере, равном количеству доступных процессоров, по сравнению с исходным однопоточным копирующим сборщиком.
Параллельно продувочного коллектор (Включено с помощью -XX: UseParallelGC). Это похоже на предыдущий сборщик параллельного копирования, но алгоритм настроен для гигабайтных куч (более 10 ГБ) на многопроцессорных машинах. Этот алгоритм сбора данных разработан для максимального увеличения пропускной способности при минимизации пауз. У него есть дополнительная политика адаптивной настройки, которая автоматически изменяет размер пространства кучи. Если вы используете этот коллектор, вы можете использовать только оригинальный коллектор mark-sweep в старом поколении (т. Е. Более новый одновременный коллектор старого поколения не может работать с этим коллектором молодого поколения).
Из этой информации кажется, что главное отличие (помимо сотрудничества с CMS) в том, что UseParallelGC поддерживает эргономику, а UseParNewGC - нет.
Параллельный сборщик мусора
UseParNewGC
Пожалуй, самый простой способ разобраться - это комбинации алгоритмов сборки мусора, разработанные Алексеем Рагозиным.
Показать фрагмент кода
<table border="1" style="width:100%"> <tr> <td align="center">Young collector</td> <td align="center">Old collector</td> <td align="center">JVM option</td> </tr> <tr> <td>Serial (DefNew)</td> <td>Serial Mark-Sweep-Compact</td> <td>-XX:+UseSerialGC</td> </tr> <tr> <td>Parallel scavenge (PSYoungGen)</td> <td>Serial Mark-Sweep-Compact (PSOldGen)</td> <td>-XX:+UseParallelGC</td> </tr> <tr> <td>Parallel scavenge (PSYoungGen)</td> <td>Parallel Mark-Sweep-Compact (ParOldGen)</td> <td>-XX:+UseParallelOldGC</td> </tr> <tr> <td>Serial (DefNew)</td> <td>Concurrent Mark Sweep</td> <td> <p>-XX:+UseConcMarkSweepGC</p> <p>-XX:-UseParNewGC</p> </td> </tr> <tr> <td>Parallel (ParNew)</td> <td>Concurrent Mark Sweep</td> <td> <p>-XX:+UseConcMarkSweepGC</p> <p>-XX:+UseParNewGC</p> </td> </tr> <tr> <td colspan="2">G1</td> <td>-XX:+UseG1GC</td> </tr> </table>
Заключение:
источник
-XX:-UseParallelGC
.-XX:+UseParallelGC
приводит к использованию параллельного GC как для молодого, так и для старого GC для современных JVM. См. Bugs.openjdk.java.net/browse/…UseParNewGC, который обычно называют «параллельным сборщиком молодого поколения», во всех отношениях аналогичен параллельному сборщику мусора (-XX: + UseParallelGC), за исключением того, что он более сложен и эффективен. Также его можно использовать с «параллельным сборщиком малой паузы».
См. FAQ по Java GC. , вопрос 22 для получения дополнительной информации.
Обратите внимание, что в UseParNewGC есть несколько известных ошибок.
источник
Использование -XX: + UseParNewGC вместе с -XX: + UseConcMarkSweepGC приведет к увеличению времени паузы для второстепенных GC по сравнению с -XX: + UseParallelGC.
Это связано с тем, что для продвижения объектов из молодого в старое поколение потребуется запустить алгоритм Best-Fit (из-за фрагментации старого поколения), чтобы найти адрес для этого объекта.
При использовании -XX: + UseParallelGC запуск такого алгоритма не требуется, так как + UseParallelGC можно настроить только с помощью MarkandCompact Collector, и в этом случае фрагментация отсутствует.
источник