Есть ли необходимость устанавливать для объектов ничего внутри функций VBA?

StackOverflow https://stackoverflow.com/questions/517006

Вопрос

Я всегда читаю, что рекомендуется ничего не устанавливать для объектов, как только я с ними закончу.Но обычно я использую их только в функциях внутри форм.

Не теряется ли ссылка и не освобождается ли память при выходе из области функции, независимо от установки объектов на Nothing?

то естьдействительно ли необходимо сделать:

Set db = Nothing
Set record_set = Nothing
Это было полезно?

Решение

VB использует так называемый сборщик мусора с подсчетом ссылок.

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

Когда счетчик достигнет нуля, объект готов к сборке мусора.Ресурсы объекта будут освобождены, как только это произойдет.Локальная переменная функции, скорее всего, будет ссылаться на объект, счетчик ссылок которого никогда не превышает 1, поэтому ресурсы объекта будут освобождены после завершения функции.

Установка переменной в Nothing это способ явного уменьшения счетчика ссылок.

Например, вы читаете файл и устанавливаете для переменной объекта файла значение Nothing сразу после ReadAll() вызов.Дескриптор файла будет немедленно освобожден, вы можете не торопиться с обработкой его содержимого.

Если вы не установили Nothing, дескриптор файла может быть открыт дольше, чем это абсолютно необходимо.

Если вы не находитесь в ситуации «необходимо разблокировать ценный ресурс», можно просто позволить переменным выйти за пределы области видимости.

Другие советы

Сбор мусора редко бывает идеальным.Даже в .NET бывают случаи, когда вам настоятельно рекомендуется заранее предложить системе выполнить сбор мусора.

По этой причине я явно закрывать и установить на Ничего наборы записей, когда я закончу с ними.

Самая последняя строка темы справки для "Набор записей.Закрыть" в справке Microsoft DAO и справочнике разработчиков Access выглядит так:

"Альтернативой методу Close является Установка значения объектной переменной в Nothing (Set dbsTemp = Nothing)."

http://msdn.microsoft.com/en-us/library/bb243098.aspx

С этим в мыслях, Эта статья из базы знаний Microsoft под названием «Как предотвратить раздувание базы данных после использования объектов доступа к данным (DAO)» сообщает, что вам следует явно закрыть базу данных, если вы не хотите, чтобы ваши базы данных раздулись.Вы заметите, что в статье немного расплывчаты детали;раздел «Причина» неясен, почти до тарабарщины.

http://support.microsoft.com/kb/289562

СИМПТОМЫ:База данных Microsoft Access начал вздуваться (или быстро расти в size) после реализации доступа к данным Objects (DAO) для открытия набора записей.

ПРИЧИНА:Если вы не отпустите recordset каждый раз, когда вы перебор кода набора записей, DAO может перекомпилироваться, используя больше памяти и увеличение размера базы данных.

БОЛЬШЕ ИНФОРМАЦИИ:Когда вы создаете Recordset (или объект QueryDef) в код, явным образом закрывать объект, когда Все готово.Microsoft Access автоматически закрывает набор записей и QueryDef в большинстве обстоятельства.Однако, если вы явно закрыть объект в файле кода, вы можете избежать случайных экземпляры, когда объект остается открытый.

Наконец, позвольте мне добавить, что я работаю с базами данных Access уже 15 лет и почти всегда позволяю локально объявленным переменным набора записей выходить за пределы области видимости без явного использования метода Close.Я не проводил никаких тестов, но, похоже, это не имеет значения.

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

Когда вы используете классический ASP (скрипты на стороне сервера), при импорте необходимо обнулить все объекты, когда вы закончите с ними, поскольку они не выходят за пределы области действия до тех пор, пока [виртуальный] сервер не будет выключен.

По этой причине все примеры сценариев MS VB всегда показывали, что объекты закрыты и ничего не установлены.Чтобы фрагменты сценария можно было использовать в таких средах, как классический ASP, где объекты не выходили за рамки.

Редко возникают другие ситуации, когда вы хотите запрограммировать длительные процессы, объекты которых не выходят за пределы области видимости, и вы обнаруживаете, что у вас заканчивается физическая память, если вы не освобождаете объекты явно.

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

Обычно я всегда помещаю это в конец своих процедур или вызываю с ним подпрограмму «CloseRecordSet», если я использую процедуры уровня модуля:

Private Sub Rawr()
On Error GoTo ErrorHandler

    'Procedural Code Here.

    ExitPoint:
        'Closes and Destroys RecordSet Objects.
        If Not Recset Is Nothing Then
            If Recset.State = 1 Then
                Recset.Close
                Conn.Close
            End If
            Set Recset = Nothing
            Set Conn = Nothing
        End If
        Exit Sub

    ErrorHandler:
        'Error Handling / Reporting Here.
        Resume ExitPoint
End Sub

Однако в этом случае процедура завершается (обычно или из-за ошибки), объекты очищаются, а ресурсы освобождаются.

Делать это таким образом совершенно безопасно, поскольку вы можете просто включить его, и он будет делать только то, что необходимо в отношении закрытия или уничтожения объекта набора записей/соединения, если он уже был закрыт (из-за ошибки во время выполнения или просто закрывайте его раньше, чем нужно, это просто гарантирует).

На самом деле это не так уж и хлопотно, и всегда лучше очищать объекты, когда вы закончите с ними, чтобы немедленно освободить ресурсы, независимо от того, что происходит в программе.

Попробуй это

If Not IsEmpty(vMyVariant) Then
    Erase vMyVariant
    vMyVariant = Empty
End If
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top