22 апр. 2021 г.

Удаление объектов в VBScript и кольцевые ссылки

Сборщик мусора в VBScript вызывается всегда по окончании блока (процедуры или функции) и пытается понять, какие объекты, созданные внутри этого блока, больше не нужны, и удаляет их.

При наличии малейших сомнений, объект останется в памяти до завершения работы Гедымина.

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

Создадим вспомогательный класс с деструктором:

Class Foo
  Public Name
  Public Other
 
  Public Default Function Init(N)
    Name = N
    Set Init = me
  End Function

  Private Sub Class_Terminate
    MsgBox Name & ": Goodbye, world!"
  End Sub
End Class

Пока кольцевых ссылок нет, код работает корректно и созданные экземпляры удаляются по завершении процедуры:

Sub Macros
  Dim f, f2, f3

  Set f = (New Foo)("f")
  Set f2 = (New Foo)("f2")
  Set f3 = (New Foo)("f3")
End Sub

Но,  стоит появиться кольцевой ссылке и объекты останутся в памяти до завершения работы Гедымина:

Sub Macros
  Dim f, f2, f3

  Set f = (New Foo)("f")
  Set f2 = (New Foo)("f2")
  Set f3 = (New Foo)("f3")

  Set f.Other = f2
  Set f2.Other = f3
  Set f3.Other = f
End Sub

Как избежать такой ситуации? Принудительно присваивать объектной переменной значение Nothing после окончания ее использования.

Много полезной информации по внутреннему устройству интерпретатора VBScript можно найти в блоге разработчика Eric Lippert.

Комментариев нет:

Отправить комментарий