У меня есть "почему это работает?" вопрос о сборке мусора (любые/все реализации: Java, Python, CLR и т.д.). Сборщики мусора освобождают объект, когда он больше не находится в какой-либо области; количество ссылок, указывающих на него, равно нулю. Мне кажется, что структура может освободиться, как только количество ссылок достигнет нуля, но все реализации, с которыми я столкнулся, ждут некоторое время, а затем освобождают многие объекты за раз. Мой вопрос: почему?
Я предполагаю, что структура хранит целое число для каждого объекта (что, по-моему, Python, потому что вы должны называть PyINCREF
и PyDECREF
при написании модулей расширения для него в C; предположительно эти функции изменяют реальный счетчик где-то). Если это так, тогда не требуется больше времени процессора для устранения объекта в момент его выхода из области видимости. Если в настоящее время требуется x наносекунд на объект, то потребуется меньше на наносекунды на объект позже?
Если мое предположение неверно и нет целого числа, связанного с каждым объектом, тогда я понимаю, почему ждет сбор мусора: ему нужно будет пройти график ссылок, чтобы определить статус каждого объекта, и этот расчет требует времени. Такой метод будет потреблять меньше памяти, чем явный метод подсчета ссылок, но я удивлен, что это быстрее или является предпочтительным методом по другим причинам. Это звучит как большая работа.
С точки зрения программирования было бы неплохо, если бы объекты были освобождены сразу же после выхода из сферы действия. Мы можем не только полагаться на деструкторы, которые выполняются, когда мы хотим, чтобы они были (одна из Python gotchas заключается в том, что __del__
не вызывается в предсказуемое время), но было бы намного проще в профиле памяти программа. Вот пример о том, как много путаницы это вызывает. На мой взгляд, преимущества программирования в системе deallocate-right-away настолько велики, что должна быть какая-то веская причина, почему все реализации, о которых я слышал, ждут до освобождения. Какая это польза?
Примечание: если прохождение по графику ссылок необходимо только для идентификации циркулярных ссылок (чистый счетчик ссылок не может), то почему бы не использовать гибридный подход? Освободите объекты, как только их число ссылок достигнет нуля, а затем также сделайте периодические развертки, чтобы искать циклические ссылки. Программисты, работающие в такой структуре, будут иметь представление о производительности/детерминированности, чтобы придерживаться некруглых ссылок, насколько это практически возможно. Это часто возможно (например, все данные в форме объектов JSON без указателей на родителей). Это как работают популярные сборщики мусора?