Это S из SOLID : Единая ответственность.
thread олицетворяет текущий контекст (как в контексте выполнения: стек стека, идентификатор потока и т. д.) асинхронного выполнения части код. То, что кусок кода в идеале должен быть одной и той же реализацией, будь то синхронный или асинхронный .
Если вы объедините их вместе в одна реализация, вы даете результирующему объекту две несвязанные причины изменения:
Если используемый вами язык поддерживает частичные классы или множественное наследование, вы можете разделить каждую причину в своем собственном суперклассе, но это сводится к тому же, что и составление двух объектов, поскольку их наборы функций не перекрываются. Это для теории.
На практике, вообще говоря, программе не нужно выполнять больше сложностей, чем необходимо. Если у вас есть один поток, работающий над конкретной задачей, без изменения этой задачи, вероятно, нет смысла делать задачи отдельными классами, а ваш код будет проще.
В контексте Java , поскольку средство уже существует, возможно, легче начать прямо с самостоятельных классов Runnable
и передать свои экземпляры в Thread
(или Executor
) экземпляров. Как только использовал для этого шаблона, его труднее использовать (или даже читать), чем простой исполняемый поток.
GC GC GC рассматривает объекты «мусор», если они недоступны через цепочку, начинающуюся с корня коллекции мусора, поэтому эти объекты будут собраны. Даже если объекты могут указывать друг на друга, чтобы сформировать цикл, они все еще мусор, если они отрезаны от корня.
См. Раздел о недоступных объектах в Приложении A: Правда о сборке мусора в Производительность платформы Java: стратегии и тактика для деталей gory.
Сбор мусора обычно не означает «очистить какой-либо объект, если ничто иное не указывает на этот объект» (это подсчет ссылок).
Итак, в вашем примере после того, как a, b и c выходят из сферы действия, они могут быть собраны GC, так как вы больше не могут обращаться к этим объектам.
yes Java Сборщик мусора обрабатывает циркулярную ссылку!
How?
Существуют специальные объекты, называемые корнями сбора мусора (корни GC).
Простое Java-приложение имеет следующие корни GC:
[/g1]
Чтобы определить какие объекты больше не используются, JVM периодически запускает то, что очень точно называют алгоритмом маркировки и развертки. Он работает следующим образом
Таким образом, если какой-либо объект недоступен из корней GC (даже если он является самореферентным или циклическим), он
Конечно, это может привести к утечке памяти, если программист забывает разыменовать объект.
[/g2]
Источник: Управление памятью Java
Билл ответил на ваш вопрос напрямую. Как сказал Амнон, ваше определение сбора мусора - это просто подсчет ссылок. Я просто хотел добавить, что даже очень простые алгоритмы, такие как сборка меток и подметания и копирования, легко обрабатывают циклические ссылки. Итак, ничего волшебного в этом нет!
Вы правы. Конкретная форма сбора мусора, которую вы описываете, называется « подсчет ссылок ». То, как это работает (концептуально, по крайней мере, большинство современных реализаций подсчета ссылок фактически реализовано совсем по-другому) в простейшем случае выглядит следующим образом:
И эта простая стратегия имеет именно ту проблему, которую вы описываете: если ссылки A B и B ссылки A, то оба их подсчета ссылок могут никогда быть меньше 1, что означает, что они wil Я никогда не собираюсь собраться.
Существует четыре способа решения этой проблемы:
Кстати, другой основной способ реализовать сборщик мусора (и я уже намекнул на это несколько раз выше), это трассировка . Трассировочный коллектор основан на концепции достижимости . Вы начинаете с некоторого корневого набора , который, как вы знаете, всегда всегда достижимый (глобальные константы, например, или класс Object
, текущая лексическая область, текущий стек кадров ), и оттуда вы отслеживаете все объекты, которые достижимы из корневого набора, а затем все объекты, которые достижимы из объектов, достижимых из набора корней и т. д., пока у вас не будет транзитивного закрытия. Все, что есть , а не в этом закрытии, является мусором.
Поскольку цикл доступен только внутри себя, но недоступен из набора корней, он будет собран.
Сборщик мусора начинается с некоторого «корневого» набора мест, которые всегда считаются «доступными», таких как регистры процессора, стек и глобальные переменные. Он работает, находя любые указатели в этих областях и рекурсивно обнаруживая все, на что они указывают. После того, как все это найдено, все else - мусор.
Есть, конечно, немало вариаций, главным образом ради скорости. Например, большинство современных сборщиков мусора являются «поколением», что означает, что они делят объекты на поколения, а по мере того, как объект становится старше, сборщик мусора идет дольше и дольше между временами, когда он пытается выяснить, остается ли этот объект действительным или нет - он просто начинает предполагать, что, если он прожил долгое время, шансы довольно хорошие, что он будет продолжать жить еще дольше.
Тем не менее основная идея остается прежней: все это основано на начиная с некоторого корневого набора вещей, который он считает само собой разумеющимся, все еще можно использовать, а затем преследуя все указатели, чтобы найти то, что еще может быть использовано.
Интересно в стороне: могут ли люди часто удивляться степени сходства между этой частью сборщика мусора и кодом для маршалинга объектов для таких вещей, как удаленные вызовы процедур. В каждом случае вы начинаете с некоторого корневого набора объектов и указатели на погоню, чтобы найти все другие объекты, к которым относятся ...
Java GC не ведут себя так, как вы описываете. Точнее сказать, что они начинаются с базового набора объектов, часто называемых «GC-корнями», и собирают любой объект, который не может быть достигнут из корня. Корни GC включают такие вещи, как:
Итак, в вашем случае, как только локальные переменные a, b и c выйдут из области действия в конце вашего метода, больше нет корней GC, которые прямо или косвенно содержат ссылку на любой из ваши три узла, и они будут иметь право на сбор мусора.
Ссылка TofuBeer имеет более подробную информацию, если вы этого хотите.
Эта статья (больше не доступна) углубляется в сборщик мусора (концептуально ... существует несколько реализаций). Соответствующая часть вашего сообщения - «A.3.4 Unreachable»:
A.3.4 Недостижимый Объект переходит в недостижимое состояние, когда нет более сильных ссылок на него. Когда объект недоступен, он является кандидатом на сбор. Обратите внимание на формулировку: только потому, что объект является кандидатом на сбор, это не означает, что он будет немедленно собран. JVM может задерживать сбор до тех пор, пока не будет немедленно потребована память, потребляемая объектом.
blockquote>