Сведения о сборщике мусора VBA

Недавно мне пришлось написать код VBA, и мне просто интересно, сталкивался ли кто-нибудь с какими-либо подробностями о том, как работает сборщик мусора VBA? Сборщик мусора .Net действительно очень хорошо документирован, но я не могу найти ни одной детали о сборщике мусора VBA, кроме расплывчатого упоминания о том, что это счетчик ссылок. Я предполагаю, что он очень похож на VB6 GC, но также не могу найти никакой информации об этом.

В частности, мне было бы интересно узнать:

  • Что вызывает GC
  • Какой алгоритм он использует (например, коллекция генерируется?)
  • Как (если вообще) он обрабатывает циклические ссылки?
  • Есть ли способ контролировать его работу

Это больше из любопытства, чем из какой-либо конкретной необходимости знать, любое понимание вообще высоко ценится!


person Jon Artus    schedule 05.11.2010    source источник
comment
Ответ Конрада — это все, что вам нужно, но я также укажу вам на Руководство программиста VB, в частности на раздел об объектных моделях, в котором обсуждается подсчет ссылок, методы tearDown и тому подобное: msdn.microsoft.com/en-us/library/aa263491(v=VS.60).aspx   -  person jtolle    schedule 06.11.2010


Ответы (1)


Далее предполагается, что VBA по-прежнему использует тот же механизм сборки мусора, что и VB6 (что весьма вероятно).

VB6 использовал сборщик мусора с подсчетом ссылок. Сборщик мусора запускается детерминировано, когда последняя ссылка на данный объект имеет значение Nothing. Установка локальных ссылок на Nothing не требуется, это происходит, когда они выходят за рамки.

Каждый объект реализует COM-интерфейс, который заботится о счетчике ссылок для этого объекта. Каждое присвоение ссылки на объект обновляет счетчики ссылок вовлеченных ссылок (т. е. счетчик старого объекта, на который ранее ссылались, уменьшается, а счетчик нового объекта увеличивается). Объект удаляется сборщиком мусора, когда его счетчик ссылок достигает 0.

Таким образом, объекты в циклических ссылках никогда не собираются в течение всего времени существования приложения VBA. Более того, VBA не предлагает способа разрывать циклические ссылки. В VB6 слабые ссылки можно было реализовать с помощью функций WinAPI.

person Konrad Rudolph    schedule 05.11.2010
comment
Установка локальных ссылок на Nothing не требуется, это происходит, когда они выходят за рамки. ‹-- Это должно быть вытатуировано на веках каждого разработчика VBA/VB6! - person Lunatik; 05.11.2010
comment
@Lunatik - Согласен!! Количество сообщений, которые я нашел при поиске информации о GC, в которых говорится, что лучше всего не устанавливать ссылки ни на что, действительно ужасает. - person Jon Artus; 05.11.2010
comment
@Jon: к сожалению, этот слух не лишен оснований. У VB6, похоже, была ошибка, которая могла вызвать некоторые висячие ссылки в переменных-членах класса (но не в локальных переменных). Я не знаю, был ли когда-либо отслежен точный источник этой ошибки, но стало общепринятой практикой использовать метод Class_Terminate для установки всех членов в Nothing. - person Konrad Rudolph; 05.11.2010
comment
Существует пограничный случай, связанный с оборванными объектами ADO IIRC, но в основном это верно. - person Lunatik; 05.11.2010
comment
VBA вообще не использует сборку мусора. Когда счетчик ссылок на объект становится равным 0, объект освобождается. Это не сбор мусора. - person Bob77; 05.11.2010
comment
@Bob: зависит от того, кого вы спросите, существуют оба определения (я предполагаю, что вы беспокоитесь о том, что в подсчете ссылок COM нет одной центральной «службы» GC, которая предоставляет GC, а скорее каждый объект имеет свой собственный сбор встроенный механизм). Но я думаю, что ясно дал понять в своем ответе что происходит в VBA, хочет ли кто-то называть это сборщиком мусора или нет. - person Konrad Rudolph; 05.11.2010
comment
Это очень забавное объяснение того, как все работает. Объекты не собираются мусором, они просто уничтожаются (например, delete this в C++). Обеспечение способа разрыва циклических ссылок не является задачей VBA или VB6. Это просто вопрос ручной реализации метода Terminate или подобного в некоторых классах, образующих цепочку. - person wqw; 05.11.2010
comment
@wqw: реализация метода Class_Terminate ничего не сделает для разрыва циклических зависимостей, поскольку этот метод никогда не будет вызываться. Конечно, вы можете реализовать вызываемый вручную метод Terminate, если вы имеете в виду именно его. Что касается того, называется ли это «сборкой мусора», еще раз: существуют оба определения. Возражать против этого - мелкая придирка. И является ли это объяснение «забавным» или нет — оно точное. Вот что важно. - person Konrad Rudolph; 06.11.2010
comment
Послушайте, циклические ссылки — это проблема COM, а не VBA, не VB6. Вы не можете сказать, что объекты собираются, когда они самоуничтожаются — никто их не собирает и не уничтожает, т. е. нет GC как модуля/действия/чего-то еще. Тем не менее, вы можете внедрить классы, которые используют пользовательский диспетчер памяти, который не освобождает память немедленно, а использует управление памятью в стиле GC (например, MSXML). объекты, собираемые GC. - person wqw; 07.11.2010
comment
@Lunatik: пограничный случай был в DAO (не ADO): [DAO предоставляет] еще один пример плохого кода разрыва. В DAO есть методы Close, которые должны вызываться в правильном порядке, и объекты также должны быть освобождены в правильном порядке (например, набор записей перед базой данных). Это единственное плохое поведение объектной модели привело к неправильному представлению о утечке памяти VB, если вы явно не установили все локальные переменные в конце функции. Это совершенно ложное представление в хорошо спроектированной объектной модели... - person onedaywhen; 08.11.2010
comment
...VB может быстрее очищать переменные в строке End Sub, чем вы можете из кода, и проверяет переменные, даже если вы явно освобождаете свои ссылки. Любое ваше усилие дублируется. Мэтью Керланд, Advanced VB6, стр. 110. - person onedaywhen; 08.11.2010