2016-08-29 11 views
1

Мне интересно, какой был бы самый правильный способ справиться с памятью при использовании VBScript. Должны ли объявлять все переменные прямо перед тем, как я их использую? Начало программы? Я понимаю глобальный vs local, однако в моем скрипте все переменные являются локальными. Я знаю, что утечки памяти никогда не будут проблемой при записи в VBScript 99,9% времени, но мне также любопытно, как «лучший» способ очистить и освободить память в скрипте. Под «лучший» Я имею в виду, сроки очистки переменных/объектов (сразу после того, как вы сделали их использование против конца сценария) и т.д.Объявление переменных Утечки памяти

Пример:

Dim fso: Set fso = CreateObject("Scripting.FileSystemObject") 
Dim arrList : Set arrList = CreateObject("System.Collections.ArrayList") 
Dim objDict: Set objDic = CreateObject("Scripting.Dictionary") 
Dim objEmail : Set objEmail = CreateObject("CDO.Message") 

Dim someArray(), x, y, z, item 

ответ

3

Сборщик мусора VBScript работает в конце каждой строки, чтобы очистить скрытые переменные и в конце каждой процедуры (end sub, end function и end property), чтобы очистить явные переменные. Объекты похожи, но добавлены ограничения. Он работает аналогично сборщику мусора VBA. В отличие от JScript ждет, пока до запуска и освобождения памяти не исчезнет 30 000 объектов.

неявные переменный является безымянным переменным - msgbox LCase(UCase("String") имеет две неявных переменный - результат UCase("String") и который передается LCase(implicitVar1) который возвращает implicitVar2, который передается в Msgbox. Переменная Explict объявляется либо DIM, либо просто использует ее как в A=5, которая создает явную переменную с именем A.

VBScript, on the other hand, has a much simpler stack-based garbage collector. Scavengers are added to a stack when they come into scope, removed when they go ou t of scope, and any time an object is discarded it is immediately freed.

https://blogs.msdn.microsoft.com/ericlippert/2003/09/17/how-do-the-script-garbage-collectors-work/

VBScript’s garbage collector is completely different. It runs at the end of every statement and procedure, and does not do a search of all memory. Rather, it keeps track of everything allocated in the statement or procedure; if anything has gone out of scope, it frees it immediately

https://blogs.msdn.microsoft.com/ericlippert/2004/12/22/t4-vbscript-and-the-terminator/

Также

https://blogs.msdn.microsoft.com/ericlippert/2004/04/28/when-are-you-required-to-set-objects-to-nothing/

https://blogs.msdn.microsoft.com/ericlippert/2004/03/01/syntax-semantics-micronesian-cults-and-novice-programmers/

ЦП - это машина на основе стека (и виртуальная машина на основе стека VBScript). Когда процессор вызывает функцию, вызывающая программа помещает параметры в стек и обратный адрес, настраивает кадр стека и выполняет скачок. Функция callee создает локальные переменные в стеке, а также возвращает на нее возвращаемое значение. Когда он возвращается, указатель стека настраивается обратно туда, где он был, который автоматически освобождает все вышеперечисленное.

3

Лучше практика объявлять все переменные, но не по той причине, которую вы предполагаете. VBScript достаточно хорош для очистки после себя, поэтому утечки памяти обычно не являются проблемой. Большую часть времени вам даже не нужно выделять объекты (Set var = Nothing), потому что они автоматически уничтожаются при выходе из контекста.

Причина, по которой вы все еще хотите объявить свои переменные, заключается в том, что вы хотите использовать Option Explicit в своих сценариях (который предусматривает объявления переменных), так что вы можете избежать проблем из-за ошибочных или иначе неинициализированных переменных. Без Option Explicit VBScript автоматически создаст отсутствующие переменные и инициализирует их пустым/нулевым значением. Глупый пример:

Dim foo : foo = 3 
Dim bar : bar = 1 
Do 
    bar = bar + fo  'mistyped variable, initilized as empty/0 
Loop Until bar > 10 
WScript.Echo bar 

Выполнение вышеуказанного приведет к созданию бесконечного цикла. Если добавить Option Explicit скрипт вместо немедленно прекратить с ошибкой выполнения:

C:\path\to\your.vbs(5, 3) Microsoft VBScript runtime error: Variable is undefined: 'fo'

+0

Я вижу. Должен ли я объявлять переменные прямо перед тем, как использовать их или на самом верху, все сразу? – tarki

+2

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

+1

Где бы вы ни вводили 'Dim' или' Const', они разбираются так, как если бы они находились в верхней части функции или файла. 'A =" Hello ": Dim A' является законным, поскольку сначала анализируется' Dim A'. (':' точно так же, как 'Enter'). –