Когда дело доходит до коллекции мусора (GC), многие люди, естественно, связывают его с Java. В Java программистам не нужно заботиться о распределении динамической памяти и сборе мусора, все это оставлено на JVM для обработки.
Как следует из названия, сборка мусора - освободить пространство, занятое мусором. Итак, в Java какие предметы будут считаться «мусором»? Таким образом, когда некоторые объекты определяются как мусор, какая стратегия должна использоваться для утилизации (свободное пространство)? Каковы типичные коллекционеры мусора в текущих коммерческих виртуальных машинах? Давайте обсудим эти вопросы один за другим. Вот контур каталогов этой статьи:
Как определить, является ли объект "мусор"?
Типичный алгоритм сбора мусора типичный сборщик мусора
1. Как определить, является ли объект «мусор»?
В этом разделе мы сначала понимаем самый основной вопрос: если мы определим, что объект - это «мусор»? Поскольку задача сборщика мусора состоит в том, чтобы переработать пространство, занятое мусорным объектом для использования новыми объектами, как сборщик мусора определяет, что объект является «мусором»? То есть, как судить, что объект может быть переработан.
В Java это связано с объектами посредством ссылок, то есть, если вы хотите управлять объектами, это должно быть сделано посредством ссылок. Тогда очевидно, что простым способом является судить, можно ли переработать объект путем отсчета. Не теряя общности, если объект не имеет никаких ссылок, связанных с ним, это означает, что объект в основном вряд ли будет использоваться в другом месте, а затем объект станет утилизируемым объектом. Этот метод становится методом подсчета ссылок.
Этот метод характеризуется его простой реализацией и высокой эффективностью, но он не может решить проблему круговых ссылок, поэтому этот метод не используется в Java (Python использует метод подсчета ссылок). Посмотрите на следующий код:
открытый класс main {public static void main (string [] args) {myObject object1 = new myObject (); Myobject object2 = new myobject (); object1.object = object2; Object2.object = Object1; объект1 = null; объект2 = null; }} класс myObject {public object = null;}Последние два предложения назначают объект1 и объект2 null, что означает, что объекты, на которые указывают объект1 и объект2, больше не доступны, а поскольку они относятся друг к другу, их ссылки не 0, тогда сборщик мусора никогда не будет их перерабатывать.
Чтобы решить эту проблему, метод анализа доступности принимается на Java. Основная идея этого метода состоит в том, чтобы искать серию объектов «корней GC» в качестве отправной точки. Если между «корнями GC» и объектом нет доступного пути, объект, как говорят, недоступен. Тем не менее, следует отметить, что объект, оцениваемый как недоступный, не обязательно может стать утилизируемым объектом. Объект, который считается недоступным, должен пройти как минимум два процесса маркировки, чтобы стать утилизируемым объектом. Если во время этих двух процессов маркировки до сих пор нет возможности стать объектом для переработки, он в основном станет утилизируемым объектом.
Что касается метода анализа доступности, я еще не понял его очень четко. Если какой -либо друг будет более ясным, пожалуйста, дайте мне несколько советов.
Давайте посмотрим пример ниже:
Object aobj = new Object (); Object Bobj = new Object (); Object cobj = new Object (); aobj = bobj; aobj = cobj; cobj = null; aobj = null;
Какая линия может сделать объект для переработки? Код в строке 7 приведет к тому, что объекты станут утилизируемыми объектами. Что касается того, почему читателям остается думать сами.
Давайте посмотрим на другой пример:
String str = new String ("hello"); softreference <string> sr = new softreference <string> (new String ("java")); SleedReference <string> wr = new SleaseReference <string> (new String ("world"));Какое из этих трех предложений сделает обработку объекта строкового объекта? Предложение 2 и 3, а предложение 2 будет определять объект String в качестве переработанного объекта, когда есть недостаточная память, а в третьем предложении объект строки будет определяться как повторный объект в любом случае.
Наконец, давайте суммируем общие ситуации, в которых объекты считаются переработанными объектами, которые обычно встречаются:
1) Отобразить значение ссылки на NULL или указать ссылку, которая уже указала на объект на новый объект, такой как следующий код:
Object obj = new Object (); obj = null; объект obj1 = new Object (); Object obj2 = new Object (); obj1 = obj2;
2) Локальная ссылка на указанный объект, такой как следующий код:
void fun () {...... for (int i = 0; i <10; i ++) {Object obj = new Object (); System.out.println (obj.getClass ()); }}Каждый раз, когда цикл выполняется, сгенерированный объект объект станет утилизируемым объектом.
3) Только слабые ссылки связаны с объектами, такими как:
SleedReference <string> wr = new SleaseReference <string> (new String ("World"));2. Типичный алгоритм сбора мусора
После определения того, какой мусор может быть переработан, сборщик мусора должен сделать, чтобы начать сбор мусора, но одна из них связана с тем, как эффективно собирать мусор. Поскольку спецификация виртуальной машины Java не дает четких правила о том, как реализовать сборщик мусора, виртуальные машины каждого производителя могут внедрить коллектор мусора по -разному, поэтому здесь обсуждаются только основные идеи нескольких общих алгоритмов сбора мусора.
1.mark-sweep (Mark-Clear) алгоритм
Это самый простой алгоритм сбора мусора. Причина, по которой он, как говорят, является самой простой, заключается в том, что проще всего реализовать и самая простая идея. Алгоритм очистки от марки делится на два этапа: этап маркировки и стадия очистки. Задача стадии маркировки состоит в том, чтобы отметить все объекты, которые необходимо переработать, и этап очистки состоит в том, чтобы переработать пространство, занятое отмеченными объектами. Конкретный процесс показан на рисунке ниже:
Из рисунка можно легко увидеть, что алгоритм очистки от марки легче реализовать, но существует серьезная проблема, что легко генерировать фрагменты памяти. Слишком много фрагментов может привести к неспособности найти достаточно места при распределении места для больших объектов в последующем процессе, и заранее вызвать новое действие сбора мусора.
2. Копирование алгоритма (копия)
Чтобы решить недостатки алгоритма Mark-Sweep, был предложен алгоритм копирования. Он делит доступную память на два часа одинакового размера по емкости, используя только один кусок за раз. Когда этот кусок памяти используется, скопируйте все еще живой объект в другой кусок, а затем очистите используемое пространство памяти одновременно, чтобы проблемы с фрагментацией памяти не возникнут. Конкретный процесс показан на рисунке ниже:
Хотя этот алгоритм прост в реализации, эффективен для запуска и нелегко генерировать фрагментацию памяти, его дорого используют пространство памяти, потому что память, которая может быть использована, уменьшается до половины исходного.
Очевидно, что эффективность алгоритма копирования во многом связана с количеством выживших объектов. Если есть много выживших объектов, эффективность алгоритма копирования будет значительно снижена.
3. Алгоритм маркировки (Mark-Collation)
Чтобы решить недостатки алгоритма копирования и в полной мере использовать пространство памяти, предлагается алгоритм маркировки. Алгоритм отмечает то же самое, что и Mark-Sweep, но после завершения отметки он не вычитывает непосредственно утилизируемые объекты, а перемещает все живые объекты на один конец, а затем очищает память за пределами конечной границы. Конкретный процесс показан на рисунке ниже:
4. Алгоритм сбора поколений
Алгоритм коллекции поколений в настоящее время используется большинством коллекционеров мусора JVM. Его основная идея состоит в том, чтобы разделить память на несколько разных регионов в зависимости от жизненного цикла выживания объекта. Вообще говоря, область кучи разделена на старое поколение и молодое поколение. Характеристикой старого поколения является то, что только небольшое количество объектов необходимо переработать каждый раз, когда собирается мусор, в то время как характеристика нового поколения заключается в том, что большое количество объектов необходимо переработать каждый раз, когда собирается мусор. Тогда наиболее подходящий алгоритм сбора может быть принят в соответствии с характеристиками разных поколений.
В настоящее время большинство коллекционеров мусора принимают алгоритм копирования для нового поколения, потому что в новом поколении большинство объектов необходимо перерабатывать каждый раз, когда собирается сбор мусора, что означает, что количество операций, которые необходимо скопировать, относительно невелико, но в действительности пространство нового поколения не делится в соответствии с соотношением 1: 1. Вообще говоря, новое поколение делится на более широкое пространство Эдема и на два меньших пространства для выживших. Каждый раз, когда используются пространство Eden и одно из мест для выживших, при переработке, все еще выживающие объекты в Eden и Survivor копируются в другое пространство выживших, а затем Eden и только что использовались пространства выживших, которые только что были использованы.
Поскольку старость заключается в том, что только небольшое количество объектов перерабатывается каждый раз, обычно используется алгоритм маркировки.
Обратите внимание, что за пределами области кучи есть еще одно поколение, которая представляет собой постоянную генерацию, которая используется для хранения классов классов, констант, описаний методов и т. Д.
3. Типичный сборщик мусора
Алгоритм сбора мусора является теоретической основой для утилизации памяти, а сборщик мусора является конкретной реализацией рециркуляции памяти. Ниже приведено описание нескольких коллекционеров мусора, предоставленных виртуальной машиной горячей точки (JDK 7). Пользователи могут комбинировать коллекционеры, используемые в каждую эпоху в соответствии с их собственными потребностями.
1. сериал/серийный старый
Серийный/серийный старый коллекционер является самым основным и старым коллекционером. Это единый коллектор потоков, и он должен приостановить все пользовательские потоки, когда он выполняет сбор мусора. Серийный коллекционер является коллекционером для нового поколения, используя алгоритм копирования, а серийный старый коллекционер является коллекционером для старого поколения, используя алгоритм маркировки. Его преимущество заключается в том, что он простой и эффективный, но его недостаток заключается в том, что он приведет к паузу пользователям.
2. Parnew
Коллекционер Parnew-это многопоточная версия серийного коллекционера, которая использует несколько потоков для сбора мусора.
3. Параллельный размахивание
Parallel Scavenge Collector - это новое поколение многопоточных коллекционеров (параллельные коллекционеры). Это не нужно останавливаться на других пользовательских потоках во время переработки. Он использует алгоритм копирования. Этот коллекционер отличается от первых двух коллекционеров. В основном это достижение контролируемой пропускной способности.
4. Параллельно старый
Parallel Old-старая версия Parallel Scavenge Collector (Parallel Collector), используя многопоточные и маркирующие алгоритмы.
5.cms
Коллекционер CMS (текущая марка Mark) является коллекционером, направленным на получение самого короткого времени паузы восстановления. Это одновременный коллекционер, который использует алгоритм Mark-Sweep.
6.g1
Коллекционер G1 является наиболее передовым достижением в современной разработке технологий коллекционеров. Это коллекционер для серверных приложений, которые могут полностью использовать мульти-CPU и многоядерные среды. Следовательно, это параллельный и коллекционер параллелей, и он может создать предсказуемую модель времени паузы.
Вот некоторые вещи о распределении памяти:
В общем направлении распределение памяти объектов выделяется на кучу. Объекты в основном распределяются в новом поколении пространства Идена и из космоса, и в редких случаях они будут непосредственно распределены в старости. Если пространство нового поколения Eden Space и из пространства недостаточно, GC будет инициирован. Если GC выполняется, пространство Eden и из пространства могут разместить объект и помещаются в пространство Eden и из космоса.
Во время процесса GC выжившие объекты в Eden Space и из пространства будут перемещены в космос, а затем пространство Eden и из пространства будут очищены. Если пространство не может быть достаточно для хранения объекта во время очистки, он перенесет объект до старости. После GC используются пространство Eden и в космос. В следующий раз, когда вы GC, выживший объект будет скопирован из космоса, а цикл будет повторяться. Когда объект ускользает от GC один раз в зоне выжившего, возраст объекта будет увеличен на 1. По умолчанию, если объект достигнет 15 лет, он перейдет в средний возраст старости.
Вообще говоря, большие объекты будут непосредственно распределены до старости. Так называемые крупные объекты относятся к объектам, которые требуют большого количества непрерывного места для хранения. Наиболее распространенным типом крупных объектов является большие массивы, такие как:
byte [] data = new Byte [4*1024*1024]
Этот тип места для хранения, как правило, будет выделяться непосредственно у пожилых людей.
Конечно, правила распределения не являются фиксированными на 100%, что зависит от того, какая комбинация коллектора мусора и соответствующие параметры JVM в настоящее время используются.
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.