Для чего нужен сборщик мусора?

Сборщик мусора (Garbage Collector) должен делать всего две вещи:

Находить мусор - неиспользуемые объекты. (Объект считается неиспользуемым, если ни одна из сущностей в коде, выполняемом в данный момент, не содержит ссылок на него, либо цепочка ссылок, которая могла бы связать объект с некоторой сущностью приложения, обрывается);

Освобождать память от мусора.

Существует два подхода к обнаружению мусора:

● Reference counting;

● Tracing

Reference counting (подсчет ссылок). Суть этого подхода состоит в том, что каждый объект имеет счетчик. Счетчик хранит информацию о том, сколько ссылок указывает на объект. Когда ссылка уничтожается, счетчик уменьшается. Если значение счетчика равно нулю, - объект можно считать мусором. Главным минусом такого подхода является сложность обеспечения точности счетчика. Также при таком подходе сложно выявлять циклические зависимости (когда два объекта указывают друг на друга, но ни один живой объект на них не ссылается), что приводит к утечкам памяти.

Главная идея подхода Tracing (трассировка) состоит в утверждении, что живыми могут считаться только те объекты, до которых мы можем добраться из корневых точек (GC Root) и те объекты, которые доступны с живого объекта. Всё остальное - мусор.

Существует 4 типа корневых точки:

● Локальные переменные и параметры методов;

● Потоки;

● Статические переменные;

● Ссылки из JNI.

Самое простое java приложение будет иметь корневые точки:

● Локальные переменные внутри main() метода и параметры main() метода;

● Поток который выполняет main();

● Статические переменные класса, внутри которого находится main() метод.

Таким образом, если мы представим все объекты и ссылки между ними как дерево, то нам нужно будет пройти с корневых узлов (точек) по всем ребрам. При этом узлы, до которых мы сможем добраться - не мусор, все остальные - мусор. При таком подходе циклические зависимости легко выявляются. HotSpot VM использует именно такой подход.

Для очистки памяти от мусора существуют два основных метода:

● Copying collectors

● Mark-and-sweep

При copying collectors подходе память делится на две части «from-space» и «to-space», при этом сам принцип работы такой:

Объекты создаются в «from-space»;

Когда «from-space» заполняется, приложение приостанавливается;

Запускается сборщик мусора. Находятся живые объекты в «from-space» и копируются в «to-space»;

Когда все объекты скопированы «from-space» полностью очищается;

«to-space» и «from-space» меняются местами.

Главный плюс такого подхода в том, что объекты плотно забивают память. Минусы подхода:

Приложение должно быть остановлено на время, необходимое для полного прохождения цикла сборки мусора;

В худшем случае (когда все объекты живые) «form-space» и «to-space» будут обязаны быть одинакового размера.

Алгоритм работы mark-and-sweep можно описать так:

● Объекты создаются в памяти;

● В момент, когда нужно запустить сборщик мусора приложение приостанавливается;

● Сборщик проходится по дереву объектов, помечая живые объекты;

● Сборщик проходится по всей памяти, находя все не отмеченные куски памяти и сохраняя их в «free list»;

● Когда новые объекты начинают создаваться они создаются в памяти доступной во «free list».

Минусы этого способа:

● Приложение не работает пока происходит сборка мусора;

● Время остановки напрямую зависит от размеров памяти и количества объектов;

● Если не использовать «compacting» память будет использоваться не эффективно.

Сборщики мусора HotSpot VM используют комбинированный подход Generational Garbage Collection, который позволяет использовать разные алгоритмы для разных этапов сборки мусора. Этот подход опирается на том, что:

● большинство создаваемых объектов быстро становятся мусором;

● существует мало связей между объектами, которые были созданы в прошлом и только что созданными объектами.

 

Как работает сборщик мусора?

Механизм сборки мусора - это процесс освобождения места в куче, для возможности добавления новых объектов.

Объекты создаются посредством оператора new, тем самым присваивая объекту ссылку. Для окончания работы с объектом достаточно просто перестать на него ссылаться, например присвоив переменной ссылку на другой объект или значение null; прекратить выполнение метода, чтобы его локальные переменные завершили свое существование естественным образом. Объекты, ссылки на которые отсутствуют, принято называть мусором (garbage), который будет удален.

Виртуальная машина Java, применяя механизм сборки мусора, гарантирует, что любой объект, обладающий ссылками, остается в памяти — все объекты, которые недостижимы из исполняемого кода, ввиду отсутствия ссылок на них, удаляются с высвобождением отведенной для них памяти. Точнее говоря, объект не попадает в сферу действия процесса сборки мусора, если он достижим посредством цепочки ссылок, начиная с корневой (GC Root) ссылки, т.е. ссылки, непосредственно существующей в выполняемом коде.

Память освобождается сборщиком мусора по его собственному «усмотрению». Программа может успешно завершить работу, не исчерпав ресурсов свободной памяти или даже не приблизившись к этой черте и поэтому ей так и не потребуются «услуги» сборщика мусора.

Мусор собирается системой автоматически, без вмешательства пользователя или программиста, но это не значит, что этот процесс не требует внимания вовсе. Необходимость создания и удаления большого количества объектов существенным образом сказывается на производительности приложений и если быстродействие программы является важным фактором, следует тщательно обдумывать решения, связанные с созданием объектов, — это, в свою очередь, уменьшит и объем мусора, подлежащего утилизации.

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: