I. Обзор
Механизм Java GC (Garbage Collection, Garbage Collection, Garbage Collection) является одним из основных отличий между Java и C++/C. Как разработчику Java, вам, как правило, не нужно писать специальный код очистки памяти и очистки мусора, и это не нужно иметь дело с проблемами утечки и переполнения памяти, и вам не нужно быть таким же осторожным, как программист на C. После такого длительного периода разработки механизм Java GC совершенствовался день ото дня, и он может почти автоматически делать за нас большую часть вещей.
Хотя java не требует от разработчиков выделения и освобождения памяти, что снижает сложность программирования для разработчиков, это также может иметь некоторые побочные эффекты:
1. 有可能不知不觉浪费了很多内存
2. JVM花费过多时间来进行内存回收
3. 内存泄露
Поэтому, как Java-программист, мы должны изучить механизм управления и рециркуляции памяти JVM, который может помочь нам устранять различные проблемы с переполнением или утечкой памяти в нашей повседневной работе, устранять узкие места в производительности, достигать более высокого уровня параллелизма и писать более эффективные программы.
2. Управление пространством памяти JVM
Согласно спецификации JVM, JVM делит память на следующие области:
1. 方法区
2. 堆区
3. 本地方法栈
4. 虚拟机栈
5. 程序计数器
Среди них область методов и куча совместно используются всеми потоками.
2.1 Область метода
В области метода хранится информация о загружаемом классе (например, имя класса, модификатор), статические переменные в классе, константы, определенные final, поля в классе, информация о методе, когда разработчик вызывает getName, isInterface и т. д. в объекте класса Когда метод используется для получения информации, эти данные извлекаются из области метода. Область метода является глобальной общей, и при определенных условиях она также будет проверена сборщиком мусора. Возникает, когда область метода использует больше памяти, чем позволяетOutOfMemory: пространство PermGenаномальный.
В виртуальной машине Hotspot эта область соответствуетПостоянное поколение, в целом сборка мусора, выполняемая на области метода, очень мала, поэтому область метода также называют одной из причин персистентной генерации, но это не означает, что сборки мусора на области метода нет вообще, и сборка мусора на нем В основном для высвобождения памяти константного пула и выгрузки загруженных классов. Сбор мусора на территории метода суров и сложен, и мы представим его позже.
Постоянный пул времени выполненияОн является частью области методов и используется для хранения литеральных констант, символических ссылок и преобразованных прямых ссылок, сгенерированных во время компиляции (символические ссылки — это места, где переменная или интерфейс кодируются как строка, а прямые ссылки преобразуются на основе символические ссылки. Результирующий адрес будет преобразован на этапе связывания классов); пул констант времени выполнения может хранить константы, сгенерированные во время выполнения, такие как метод intern() класса String, в дополнение к хранению констант времени компиляции. заключается в том, что String поддерживает постоянный пул, если вызываемый символ «abc» уже находится в пуле констант, возвращается адрес строки в пуле, в противном случае в пул добавляется новая константа и возвращается адрес.
Соответствующие параметры области метода JVM, минимальное значение:--XX:PermSize
; максимум--XX:MaxPermSize
.
2.2 Область кучи
Область кучи является наиболее важной областью для понимания механизма JavaGC. В памяти, управляемой JVM, область кучи является самой большой частью, а область кучи также является основной областью памяти, управляемой механизмом JavaGC.Область кучи совместно используется всеми потоками и создается при запуске виртуальной машины. Область кучи используется для хранения экземпляров объектов и значений массивов, можно считать, что здесь размещены все объекты, созданные new в java.
Для размера кучи вы можете передать параметр-Xms
а также-Xmx
Для контроля -Xms — это последняя куча памяти, которая применяется при запуске JVM, по умолчанию — 1/64 физической памяти, но менее 1 ГБ; -Xmx — это максимальная куча памяти, к которой может обращаться JVM, по умолчанию 1 /4 физической памяти, но менее 1 ГБ. По умолчанию, когда оставшееся пространство кучи составляет менее 40%, JVM увеличит размер кучи до -Xmx.-XX:MinHeapFreeRadio
параметр для управления этим соотношением; когда свободная память кучи превышает 70%, JVM уменьшит размер кучи до размера, указанного параметром -Xms, который можно передать через-XX:MaxHeapFreeRatio
указать это соотношение. Для системы, чтобы избежать частой настройки размера Heap во время работы, мы обычно устанавливаем -Xms и -Xmx одинаковыми.
Чтобы сделать освобождение памяти более эффективным (позже мы объясним, почему требуется разделение по поколениям), начиная с Sun JDK 1.2, для кучи был принят метод управления по поколениям, как показано на следующем рисунке:
Молодое поколение
Когда объект создается, память сначала сохраняется вмолодое поколениеРаспределить (обратите внимание, что большие объекты могут быть размещены непосредственно в старом поколении). Срабатывает, когда молодое поколение нуждается в переработкеMinor GC(также известен какYoung GC).
молодое поколениеEden Spaceи две штуки одного размераSurvivor Space(также известный как S0 и S1), размер нового поколения можно настроить с помощью параметра -Xmn, или размер нового поколения можно настроить с помощью параметра -Xmn.-XX:SurvivorRadio
чтобы настроить размер Eden Space и Survivor Space. Различные методы GC будут по-разному делить Eden Space и Survivor Space в соответствии с этим значением, а некоторые методы GC будут динамически регулировать размер Eden, S0 и S1 в соответствии с условиями работы.
Память области Эдема молодого поколения непрерывна, поэтому ее выделение будет очень быстрым, восстановление области Эдема также происходит очень быстро (поскольку в большинстве случаев время выживания объекта области Эдема очень короткое, и алгоритм восстановления копии, используемый в районе Эдема, этот алгоритм очень эффективен, когда доля живых объектов невелика, о чем будет подробно рассказано позже).
Если после выполнения сборки мусора по-прежнему недостаточно выделенной памяти и дальнейшее расширение невозможно,OutOfMemoryError:Java Heap Spaceаномальный.
Старое поколение
старостьОбъекты, которые хранятся в молодом поколении и все еще сохраняются после нескольких сборок мусора, можно понимать как более старые объекты, такие как объекты кеша; вновь созданные объекты могут также выделять память непосредственно в старом поколении.Есть два основных случая: объект, который можно задать через параметры запуска-XX:PretenureSizeThreshold=1024
, что указывает на то, что при превышении возраста он не будет выделяться в молодом поколении, а будет выделяться непосредственно в старом поколении. Этот параметр используется в молодом поколенииParallel Scavenge GCНедопустимо, поскольку он будет решать, какому объекту выделять память непосредственно в старом поколении в соответствии с текущей ситуацией; другой объект является большим объектом массива, и в объекте массива нет ссылок на внешний объект.
Когда старость заполнена, старость должна быть собрана.Сборка мусора старости называетсяMajor GC(также называемыйFull GC).
Объем памяти, занимаемый старым поколением, равен значению, соответствующему -Xmx, минус значение, соответствующее -Xmn.
2.3 Стек собственных методов
собственный стек методовИспользуется для поддержки выполнения собственных методов, сохраняет состояние каждого вызова собственного метода. Стек собственных методов и стек методов виртуальной машины имеют одинаковый механизм работы. Единственное различие между ними заключается в том, что стек виртуальной машины выполняет методы Java, а стек собственных методов используется для выполнения собственных методов. Во многих виртуальных машинах (например, Sun JDK по умолчанию (виртуальная машина HotSpot) будет использовать собственный стек методов вместе со стеком виртуальной машины.
2.4 Регистр счетчика программ
счетчик командЭто относительно небольшая область памяти, которая может быть регистрами ЦП или памятью операционной системы. Она в основном используется для указания номера строки байт-кода, выполняемого текущим потоком. Его можно понимать как индикатор номера строки текущего потока. Когда интерпретатор байт-кода работает, он выберет следующую инструкцию оператора, изменив значение этого счетчика. Каждый программный счетчик используется только для записи номера строки одного потока, поэтому он является частным потоком (один поток имеет один программный счетчик).
Если программа выполняет метод Java, счетчик записывает адрес исполняемой инструкции байт-кода виртуальной машины; если программа выполняет собственный (собственный, написанный на языке C) метод, значение счетчика равно Undefined, поскольку Счетчик программ записывает только текущий адрес инструкции, переполнения памяти нет, поэтому счетчик программ также является единственной областью во всех областях памяти JVM, где OutOfMemoryError не определен.
2.5 Стек JVM
стек виртуальных машинОн занимает память операционной системы, и каждый поток соответствует стеку виртуальной машины, который является частным для потока, и распределение происходит очень эффективно. При выполнении каждого метода потока будет создан кадр стека (Statck Frame).В кадре стека хранится таблица локальных переменных, операционная станция, динамическая ссылка, выход из метода и т. д. хранится во фрейме стека. Стек JVM помещается в стек, и когда выполнение метода завершено, фрейм стека извлекается из стека.
В таблице локальных переменных хранятся соответствующие локальные переменные метода, включая различные базовые типы данных, ссылки на объекты и адреса возврата. В таблице локальных переменных только типы long и double занимают 2 пространства локальных переменных (Slot, для 32-битной машины Slot — это 32 бита), а остальные — 1 слот. Следует отметить, что таблица локальных переменных определяется во время компиляции, а пространство, выделенное для выполнения метода, полностью определяется в кадре стека и не изменится в течение жизненного цикла метода.
В стеке виртуальной машины определены два исключения.Если глубина стека вызова потока превышает максимальную глубину, разрешенную виртуальной машиной, он будет выброшен.StatckOverFlowError(переполнение стека), однако большинство виртуальных машин Java позволяют динамически увеличивать размер стека виртуальной машины (небольшое количество из них имеют фиксированную длину), поэтому поток может продолжать обращаться к стеку до тех пор, пока памяти не станет недостаточно. на этот раз он броситOutOfMemoryError(недостаточно памяти).
2.6 Режим доступа к объектам Java
Вообще говоря, доступ к ссылке Java включает в себя три области памяти: стек JVM, куча и область методов. В простейшей ссылке на локальную переменную:Object objRef = new Object()
Например:
- Объект objRef представляет собой локальную ссылку, хранящуюся в таблице локальных переменных стека JVM, представляющую данные ссылочного типа;
- new Object() хранится в куче как данные объекта экземпляра;
- В куче также записывается адрес данных типа (интерфейс, метод, поле, тип объекта и т. д.), которые можно запросить для этого объекта Object, а фактические данные хранятся в области метода;
В спецификации виртуальной машины Java указаны только ссылки на объекты, и нет правил для доступа к конкретным объектам через ссылки на ссылочные типы.Однако в настоящее время есть две основные реализации:
2.6.1 Доступ с помощью ручки
При реализации доступа к дескриптору отдельная область памяти делится на пул дескрипторов в куче JVM, а указатели на данные экземпляра объекта (в куче) и данные типа объекта (в области метода) хранятся в пуле дескрипторов. Эта реализация очень стабильна, потому что адреса представлены дескрипторами.
2.6.2 Доступ через прямой указатель
При прямом доступе по указателю фактический адрес объекта в куче хранится в ссылке, а информация об объекте, хранящаяся в куче, содержит данные соответствующего типа в области метода. Самым большим преимуществом этого метода является скорость, которая используется в виртуальной машине HotSpot.
3. Распределение памяти JVM
Память, занимаемая Java-объектами, в основном реализуется в куче, а поскольку куча совместно используется потоками, ее необходимо блокировать при выделении памяти в куче, что приводит к относительно высоким накладным расходам на создание объектов. Когда в куче недостаточно места, будет запущена сборка мусора.Если места по-прежнему недостаточно после сборки мусора, будет сгенерировано исключение OutOfMemory.
Чтобы повысить эффективность выделения памяти, виртуальная машина HotSpot в районе Eden молодого поколения использует две технологии для ускорения выделения памяти, а именно:bump-the-pointerа такжеTLAB (локальные буферы распределения потока). Так как область Эдема непрерывна, ядром технологии bump-the-pointer является отслеживание последнего созданного объекта.При создании объекта необходимо только проверить, достаточно ли памяти позади последнего объекта, что значительно ускоряет увеличить скорость выделения памяти. ; в то время как технология TLAB предназначена для многопоточности,
Он выделяет независимое пространство в Eden Space нового поколения для каждого вновь созданного потока Это пространство называется TLAB (Thread Local Allocation Buffer), и его размер рассчитывается JVM в соответствии с текущей ситуацией. доступный-XX:TLABWasteTargetPercent
Чтобы установить процент Eden Space, который он может занимать, по умолчанию используется значение 1%. Выделение памяти в TLAB не требует блокировки. Как правило, JVM сначала выделяет память в TLAB. Если объект слишком велик или пространство TLAB израсходовано, оно все равно будет выделено в куче. Поэтому при написании программ несколько небольших объектов выделяются эффективнее, чем большие. можно добавить в параметры запуска-XX:+PrintTLAB
для просмотра использования пространства TLAB.
Если объект прожил достаточно долго в молодом поколении без очистки (то есть выжил после нескольких Minor GC), он будет скопирован в старое поколение.Пространство старого поколения, как правило, больше, чем у молодого поколения В старом поколении хранится больше объектов, и меньше GC возникает, чем в молодом поколении. Когда старому поколению не хватает памяти, будет выполнен основной сборщик мусора, также называемый полным сборщиком мусора.
можно использовать-XX:+UseAdaptiveSizePolicy
Переключатель используется для контроля того, принята ли стратегия динамического управления.Если она управляется динамически, размер каждой области в куче Java и возраст перехода к старому поколению динамически корректируются.
Если объект относительно большой (например, длинная строка или большой массив) и в молодом поколении недостаточно места, большой объект будет напрямую выделен старому поколению (большие объекты могут вызвать ранний сборщик мусора, поэтому они должны следует использовать экономно, и следует избегать короткоживущих крупных объектов). использовать-XX:PretenureSizeThreshold
Для управления размером объектов, которые напрямую переводятся в старое поколение, объекты, размер которых превышает это значение, будут напрямую выделены старому поколению.
В-четвертых, метод восстановления памяти
JVM освобождает память в области кучи и методов через GC, и этот процесс выполняется автоматически. Когда дело доходит до механизма сборки мусора в Java, он в основном выполняет три задачи: определяет, какая память должна быть освобождена, определяет, когда необходимо выполнить сборку мусора, как выполнять сборку мусора. JVM в основном использует коллектор для реализации сборщика мусора. К основным сборщикам относятся сборщик подсчета ссылок и сборщик отслеживания.
4.1 Коллекторы подсчета ссылок
Счетчик ссылок использует децентрализованный метод управления и записывает, ссылаются ли на объект через счетчик. Когда счетчик равен 0, это означает, что объект больше не используется и может быть переработан, как показано на рисунке:
На приведенном выше рисунке после того, как ObjectA освобождает ссылку на ObjectB, счетчик ссылок ObjectB становится равным 0, и память, занимаемая ObjectB, может быть освобождена.
Счетчик ссылок необходимо увеличивать или уменьшать каждый раз, когда присваивается объект, который имеет определенное потребление. Кроме того, счетчик ссылок не может добиться повторного использования для циклических сценариев ссылок. Например, в приведенном выше примере, если ObjectB и ObjectC ссылаются друг на друга, даже если ObjectA освобождает ссылки на ObjectB и ObjectC, ObjectB и ObjectC не могут быть восстановлены.Поэтому для такого языка, как java, который будет формировать сложную ссылку отношения, счетчик ссылок Это очень неуместно, и SunJDK не использует этот метод при реализации GC.
4.2 Сборщик следов
Сборщик отслеживания использует метод централизованного управления, который записывает состояние ссылок на данные в глобальном масштабе. Запускается на основе определенных условий (например, по времени, когда недостаточно места), ссылочные отношения объектов необходимо сканировать из корневой коллекции во время выполнения, что может привести к приостановке приложения. ЕстьКопирование,Марк-разверткаа такжеМарк-КомпактТри алгоритма реализации.
Копирование
Метод копирования заключается в сканировании уцелевших объектов из корневого набора, и копировании найденных уцелевших объектов в новое совершенно неиспользуемое пространство, как показано на рисунке:
Методу сборщика копий нужно только просканировать все уцелевшие объекты из корневого множества.Когда в пространстве, подлежащем рекультивации, уцелевших объектов мало, алгоритм копирования будет более эффективным (данный алгоритм используется в районе Эдема молодого генерация), а стоимость этого заключается в добавлении пустого пространства памяти и перемещении объектов.
Отметка-удаление
Метод маркировки-очистки заключается в том, чтобы начать сканирование с корневого набора, отметить уцелевшие объекты, а после маркировки просканировать немаркированные объекты во всем пространстве и очистить их.Процесс маркировки и очистки показан на следующем рисунке:
Синяя часть на приведенном выше рисунке — это уцелевшие объекты, на которые есть ссылки, а коричневая часть — перерабатываемые объекты, на которые нет ссылок. На этапе маркировки для маркировки объектов все объекты будут сканироваться один раз, а процесс сканирования занимает много времени.
На этапе очистки повторно используются объекты, на которые нет ссылок, а уцелевшие объекты сохраняются. Распределитель памяти будет содержать справочный список свободного места, и когда будет запрос на выделение, он запросит справочный список свободного места для выделения.
Действие Mark-Sweep не требует перемещения объекта и обрабатывает только его неживые объекты. Он более эффективен, когда в пространстве много живых объектов, но поскольку метка-зачистка напрямую освобождает память, занятую неживыми объектами, это вызовет фрагментацию памяти.
Марк-Компакт
Пометка-сжатие и пометка-очистка аналогичны пометке живых объектов, но обработка после очистки отличается.После очистки памяти, занятой объектами, пометка-сжатие переместит все живые объекты в свободное пространство в левом конце, а затем Затем обновите указатель, ссылающийся на его объект, как показано на следующем рисунке:
Очевидно, что сжатие меток перемещает уцелевшие объекты на основе очистки меток, решает проблему фрагментации памяти и получает больше непрерывного пространства памяти для повышения эффективности распределения.Однако, поскольку объекты необходимо перемещать, поэтому стоимость также выше. .
Пять, процесс GC в виртуальной машине
5.1 Зачем нужна переработка по поколениям?
В начале GC JVM выполняется методом mark-sweep-compact, который не очень эффективен, потому что по мере того, как выделяется все больше и больше объектов, список объектов становится все больше и больше, а сканирований и перемещений становится все больше и больше. сложно.Чем больше времени это занимает, тем медленнее происходит восстановление памяти. Однако, согласно анализу Java-приложений, обнаружено, что время выживания большинства объектов очень короткое, и лишь небольшая часть периода выживания данных относительно велика.Пожалуйста, посмотрите следующую статистику времени выживания памяти Java объекты:
Как видно из графика, большинство объектов живут очень недолго, и с течением времени выделяется все меньше и меньше объектов.
5.2 Процесс GC в виртуальной машине
После приведенного выше введения мы уже знаем, почему JVM необходимо перерабатывать по поколениям.Давайте подробно рассмотрим весь процесс переработки.
-
На начальном этапе вновь созданный объект размещается в области Эдема, и оба пространства выжившего пусты.
-
Когда область Эдема заполнена, срабатывает мелкий мусор.
-
После сканирования и маркировки уцелевшие объекты копируются в S0, а не уцелевшие объекты перерабатываются
-
В следующем Minor GC ситуация в области Эдема такая же, как и выше, объекты, на которые нет ссылок, перерабатываются, а уцелевшие объекты копируются в область выживших. Однако в оставшейся области все данные S0 копируются в S1.Следует отметить, что возраст двух объектов, перемещенных в S0 во время последнего незначительного процесса GC, будет увеличен на 1 после копирования в S1. В это время область S0 области Эдема пустеет, все уцелевшие данные копируются в область S1, а в области S1 находятся объекты разного возраста.Процесс показан на следующем рисунке:
-
В следующий раз, когда MinorGC повторяет этот процесс, на этот раз две области выжившего меняются местами, выжившие объекты копируются в S0, возраст выживших объектов увеличивается на 1, а область Эдема и другая выжившая область очищаются.
-
Процесс Повышения показан ниже.После нескольких Minor GC, когда возраст выжившего объекта достигает порога (настраивается параметрами, по умолчанию 8), он будет повышаться из молодого поколения в старое поколение.
-
Поскольку MinorGC выполняется снова и снова, новые объекты будут переведены в старое поколение.
-
Вышеупомянутое в основном охватывает все процессы утилизации всего молодого поколения. В конце концов, MajorGC произойдет в старом поколении, а пространство в старом поколении будет расчищено и сжато.
Как видно из вышеописанного процесса, область Эдема представляет собой непрерывное пространство, и один из Выживших всегда пуст. После GC и репликации один Выживший сохраняет живые на данный момент объекты, а содержимое области Эдема и другой области Survivor больше не нужно, и может быть опустошено напрямую.При следующем GC роли двух Выживших будут взаимодействовать друг с другом снова. Поэтому эффективность выделения памяти и очистки памяти таким способом чрезвычайно высока.Этот способ сборки мусора известен"Остановить и скопировать"Метод очистки (копирование области Эдема и еще живых объектов в одном Survivor в другой Survivor), это не значит, что метод очистки с остановкой копирования очень эффективен, на самом деле он только в этом случае (исходя из жизненного цикла большинство объектов) очень короткий факт) эффективен, если использовать остановку репликации в старости очень нецелесообразно.
Старое поколение хранит гораздо больше объектов, чем молодое поколение, и недостатка в больших объектах нет, при использовании алгоритма стоп-копии для очистки памяти старого поколения он достаточно неэффективен. Как правило, алгоритм, используемый в старости, представляет собой алгоритм пометочного сжатия, то есть: пометить все еще уцелевшие объекты (со ссылками) и переместить все уцелевшие объекты в один конец, чтобы обеспечить непрерывность памяти. Когда происходит Minor GC, виртуальная машина проверяет, превышает ли размер каждого продвижения в старое поколение оставшееся пространство старого поколения.Если он больше, он напрямую запускает Full GC, в противном случае проверьте, установлен ли он-XX:+HandlePromotionFailure
(Разрешить сбой гарантии), если разрешено, будет выполняться только MinorGC, и в это время можно допустить сбой выделения памяти; если не разрешено, все равно выполняется Full
GC (это означает, что если установлено-XX:+Handle PromotionFailure
, то запуск MinorGC вызовет одновременно Full GC, даже если в старости еще много памяти, так что лучше этого не делать).
Что касается повторного использования области метода, то есть постоянного поколения, существует два типа повторного использования постоянного поколения: константы в пуле констант, бесполезная информация о классе, и повторное использование констант очень просто и может быть повторно использовано без ссылок. За утилизацию бесполезных классов должны быть гарантированы три балла:
1. 类的所有实例都已经被回收
2. 加载类的ClassLoader已经被回收
3. 类对象的Class对象没有被引用(即没有通过反射引用该类的地方)
Переработка постоянного поколения не требуется, а перерабатывать ли класс можно задать параметрами.
6. Сборщик мусора
Благодаря приведенному выше введению мы узнали о процессе утилизации памяти JVM, а в виртуальной машине GC выполняется сборщиком мусора, поэтому в практических сценариях применения нам необходимо выбрать подходящий сборщик мусора в соответствии с ситуацией приложения. давайте представим сборщик мусора.
6.1 Последовательный коллектор
Последовательный сборщик Конфигурация по умолчанию, используемая клиентской виртуальной машиной в JavaSE5 и 6. Это самый простой сборщик, который больше подходит для систем с одним процессором. В последовательном сборщике как второстепенные, так и основные процессы GC используют один поток для сборки мусора.
сцены, которые будут использоваться
Прежде всего, последовательный сборщик мусора обычно используется в сценариях, где требования к приостановке приложений не очень высоки и работают в режиме клиента, он использует только одно ядро ЦП для сборки мусора. При текущих аппаратных условиях последовательный сборщик мусора может управлять многими приложениями с небольшим объемом памяти и может гарантировать относительно небольшие паузы (около нескольких секунд в случае полного сбора мусора). Другой сценарий, в котором обычно используется последовательный сборщик мусора, — это когда на одной машине запущено несколько виртуальных машин JVM (количество виртуальных машин JVM больше, чем количество ядер ЦП).В этом сценарии, когда JVM выполняет сборку мусора, используется только один процесс. , Это не окажет большого влияния на другие JVM. Наконец, в некоторых аппаратных устройствах с относительно небольшим объемом памяти и относительно небольшим количеством ядер ЦП более целесообразно использовать последовательный сборщик.
Связанные команды параметров
1 Включите последовательный коллектор:-XX:+UseSerialGC
2 Пример командной строки:
java -Xmx12m -Xms3m -Xmn1m -XX:PermSize=20m -XX:MaxPermSize=20m -XX:+UseSerialGC -jar c:\javademos\demo\jfc\Java2D\Java2demo.jar
6.2 Параллельные коллекторы
Параллельный сборщик использует многопоточный метод для сборки мусора, и параллельный метод может обеспечить большую пропускную способность ЦП. Он не влияет на работающее приложение, когда оно не является сборщиком мусора, и использует многопоточность для повышения скорости восстановления, когда процесс является сборщиком мусора, поэтому параллельный сборщик очень подходит для пакетной обработки. Конечно, если приложение предъявляет высокие требования к приостановке программы, рекомендуется использовать параллельный сборщик, описанный ниже. По умолчанию на машине с N ЦП число потоков, которые должны быть переработаны параллельно, равно N. Конечно, количество параллелизма можно контролировать с помощью параметра:-XX:ParallelGCThreads=<desired number>
. Параллельный сборщик — это метод повторного использования по умолчанию, используемый на компьютерах уровня сервера (процессор больше 2 и память больше 2 ГБ).
На машине с одноядерным процессором, даже если параллельный сборщик сконфигурирован, сборщик по умолчанию по-прежнему используется для фактического сбора. Если на машине только два ЦП, эффект от использования параллельного сборщика и сборщика по умолчанию почти одинаков, только когда количество ЦП больше 2, время паузы сбора молодого поколения будет сокращено.
Сценарии применения
Параллельный сборщик подходит для ситуаций, когда требуется несколько ЦП и короткие паузы. Обычно некоторые пакетные приложения, такие как печать отчетов, запросы к базе данных, могут использовать параллельный сборщик.
Многопоточность в молодом поколении и однопоточность в старом поколении
1 Включить команду:-XX:+UseParallelGC
2 Пример командной строки:
java -Xmx12m -Xms3m -Xmn1m -XX:PermSize=20m -XX:MaxPermSize=20m -XX:+UseParallelGC -jar c:\javademos\demo\jfc\Java2D\Java2demo.jar
И молодое, и старое поколения используют многопоточность
1 Включить команду:-XX:+UseParallelOldGC
Когда параметр -XX:+UseParallelOldGC включен, сборки мусора как молодого, так и старого поколения являются многопоточными, а также многопоточными на этапе уплотнения. Поскольку виртуальная машина HotSpot использует алгоритм стоп-копирования в молодом поколении, в молодом поколении нет процесса сжатия, а в старом поколении используется алгоритм маркировки-развертки-сжатия, поэтому в старое поколение.
2 Пример командной строки:
java -Xmx12m -Xms3m -Xmn1m -XX:PermSize=20m -XX:MaxPermSize=20m -XX:+UseParallelOldGC -jar c:\javademos\demo\jfc\Java2D\Java2demo.jar
6.3 Коллектор CMS (одновременная развертка меток)
Сборщик CMS в основном используется для постоянной области, которая пытается уменьшить паузы во время сборки мусора в виде многопоточного параллелизма. Сборщик CMS не копирует и не перемещает живые объекты.
Сценарии применения
Сборщик CMS в основном используется в сценариях, где приложения предъявляют высокие требования к времени паузы, например, настольные UI-приложения должны своевременно реагировать на события операций пользователя, серверы должны иметь возможность быстро реагировать на запросы клиентов или базы данных должны реагировать быстро запрашивать запросы и т. д.
Связанные параметры команды
1 Включите сборщик CMS:-XX:+UseConcMarkSweepGC
2 Установите количество потоков:-XX:ParallelCMSThreads=<n>
3 Пример командной строки:
java -Xmx12m -Xms3m -Xmn1m -XX:PermSize=20m -XX:MaxPermSize=20m -XX:+UseConcMarkSweepGC -XX:ParallelCMSThreads=2 -jar c:\javademos\demo\jfc\Java2D\Java2demo.jar
6.4 Коллектор G1
G1 — это Garbage First, новый сборщик, появившийся в java 7, и его цель — заменить существующий сборщик CMS. G1 обладает характеристиками параллелизма, параллелизма, добавочного сжатия, периода времени паузы и т. д., которые здесь подробно не рассматриваются.
Связанные параметры команды
1 Включите коллектор G1:-XX:+UseG1GC
2 Пример командной строки:
java -Xmx12m -Xms3m -XX:+UseG1GC -jar c:\javademos\demo\jfc\Java2D\Java2demo.jar
Пожалуйста, укажите источник:Оригинальная ссылка