Циркулярные ссылки в Javajava


Answers

Сборщик мусора знает, где находятся корневые объекты: статика, локали в стеке и т. Д., И если объекты недоступны из корня, они будут восстановлены. Если они достижимы, то им нужно придерживаться.

Question

Учитывая агрегацию экземпляров класса, которые относятся друг к другу в сложной, круглой форме: возможно ли, что сборщик мусора не сможет освободить эти объекты?

Я смутно помню, что это было проблемой в JVM в прошлом, но я думал, что это было решено много лет назад. Тем не менее, некоторые исследования в jhat показали, что циркулярная ссылка является причиной утечки памяти, с которой я столкнулся сейчас.

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




Если я правильно помню, то, согласно спецификациям, есть только гарантии того, что JVM не может собрать (что-то доступное), а не то, что он соберет.

Если вы не работаете с JVM в реальном времени, большинство современных сборщиков мусора должны иметь возможность обрабатывать сложные справочные структуры и идентифицировать «подграфы», которые можно безопасно исключить. Эффективность, латентность и вероятность этого улучшаются с течением времени, поскольку все больше идей исследований проникают в стандартные (а не исследовательские) виртуальные машины.




Спецификация Java говорит, что сборщик мусора может мусор собирать ваш объект ТОЛЬКО Если он недоступен из любого потока.

Достижимое означает, что есть ссылка или цепочка ссылок, которая ведет от А до В, и может проходить через С, D, ... Z для всех, что она заботится.

JVM, не собирающий вещи, не был проблемой для меня с 2000 года, но ваш пробег может отличаться.

Совет. Сериализация Java кэширует объекты, чтобы сделать передачу сетки объектов эффективной. Если у вас много больших, переходных объектов, и вся ваша память становится забитой, сбросьте свой сериализатор, чтобы очистить кеш.




В этом вопросе печально известны ссылочные счетные GC. Примечательно, что SunS JVM не использует счетный счетный GC.

Если объект не может быть доставлен из корня кучи (как правило, как минимум, через загрузчики классов, если ничего больше 0, тогда объекты будут уничтожены, поскольку они не будут скопированы во время типичного Java GC в новую кучу.




Сборщик мусора - очень сложная часть программного обеспечения - он был протестирован в огромном наборе тестов JCK. Это НЕ идеально, но есть очень хороший шанс, что до тех пор, пока java-компилятор (javac) будет компилировать все ваши классы, и JVM будет его создавать, тогда вы должны быть хорошими.

Опять же, если вы держите ссылки на корень этого графа объектов, память НЕ будет освобождена, но если вы знаете, что делаете, вы должны быть в порядке.