Действительно ли необходимо очистить объект / освободить массив в VB6 / VBA (за / против?) - PullRequest
8 голосов
/ 06 октября 2009

Многое из того, что я узнал о VB, я узнал, используя статический анализ кода (в частности, анализатор проектов Aivosto). И одна из вещей, которую он проверяет, - очищали ли вы все объекты и массивы. Раньше я делал это вслепую, потому что ПА так сказал. Но теперь, когда я знаю немного больше о том, как VB высвобождает ресурсы, мне кажется, что эти вещи должны происходить автоматически. Это унаследованная функция от pre VB6, или есть причина, по которой вы должны явно установить нулевые объекты и использовать Erase для массивов?

Ответы [ 5 ]

14 голосов
/ 06 октября 2009

Мэтт Керланд, автор Advanced Visual Basic 6 , который знает о Visual Basic больше, чем большинство из нас, думает, что это пустая трата усилий. Рассмотрим эту цитату (p110) о DAO, библиотеке доступа к данным COM, которая в первую очередь предназначена для ядра СУБД Access:

еще один пример плохого кода разрыва. В DAO есть методы Close, которые должны быть вызывается в правильном порядке, а объекты должны быть выпущены в правильный порядок (Recordset) до базы данных, например). это поведение одной плохой объектной модели привело к заблуждению, что утечки VB память, если вы явно не установите все локальные переменные к нулю на конец функции. Это совершенно ложное представление в хорошо продуманная объектная модель. VB может очистить переменные быстрее в конце Подстрока, чем вы можете из кода, и он проверяет переменные, даже если вы явно отпустите ваши ссылки. Любое ваше усилие дублируется.

4 голосов
/ 06 октября 2009

Проблема, насколько я понимаю, связана с тем, что VB6 (и его предшественники) имеют корни в COM и системе сбора мусора с подсчетом ссылок.

Представьте, например, что вы объявляете ссылку на объект из сторонней библиотеки. Этот объект имеет счетчик ссылок COM, который используется как для поддержания его работоспособности, так и для определения момента его уничтожения. Он не уничтожается, когда вы устанавливаете его в Nothing, но когда счетчик ссылок объекта достигает нуля.

Теперь не все компоненты COM были написаны на Visual Basic. Некоторые были написаны на C или C ++. Структурная обработка исключений существует не во всех языках. Таким образом, если произошла ошибка, счетчик ссылок на объект не гарантированно был должным образом уменьшен, и было известно, что COM-объекты зависают дольше, чем предполагалось. Это не было проблемой с Visual Basic, как таковой. Это была проблема COM. (И это, как вы могли заметить, именно поэтому .NET не использует подсчет ссылок.)

Вот почему разработчики Visual Basic стали одержимы освобождением ссылок на объекты до выхода из подпрограмм. Вы просто не знаете, какой компонент вы размещаете под капотом. Но когда вы отпускаете ссылку на него, вы, по крайней мере, публикуете счетчик ссылок на него. Это стало почти религиозной мантрой. Объявить, использовать, выпустить. Это был COM способ делать вещи.

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

2 голосов
/ 07 октября 2009

Вы читали эту веб-страницу Aivosto (от создателей Project Analyzer)?

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

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

0 голосов
/ 06 октября 2009

Да, установите все объекты на Ничто и очистите как можно больше. VB6 известен тем, что имеет утечки памяти, когда не убирает ваши вещи. Сборка мусора была ниже нормы в VB6 / VBA.

0 голосов
/ 06 октября 2009

Я всегда делаю это для хорошей практики, вы никогда не знаете, что может сделать исключение, если вы попадете в него, и ваши объекты не будут освобождены. Вы должны связать их в операторах finally и убедиться, что они не используют память, иначе вы можете столкнуться с утечкой памяти.

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

...