我想知道在使用VBScript时处理内存的最正确方法是什么。应该在使用之前声明所有变量吗?该计划的开始?我理解全局vs本地,但在我的脚本中,所有变量都是本地的。我知道在99.9%的时间内用VBScript写入时内存泄漏永远不会成为问题,但我也很好奇最好的'在脚本中清除和释放内存的方法。最好的'我的意思是,清除变量/对象的时间(在你完成使用它们与脚本结束之后)等等。
一个例子:
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
答案 0 :(得分: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运行时错误:变量未定义:'fo'
答案 1 :(得分: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有一个更简单的基于堆栈的垃圾收集器。当它们进入范围时,清除器被添加到堆栈中,当它们进入范围时被移除,并且任何时候丢弃对象,它立即被释放。
https://blogs.msdn.microsoft.com/ericlippert/2003/09/17/how-do-the-script-garbage-collectors-work/
VBScript的垃圾收集器完全不同。它在每个语句和过程结束时运行,并且不搜索所有内存。相反,它会跟踪声明或程序中分配的所有内容;如果有任何事情超出了范围,它会立即释放它
https://blogs.msdn.microsoft.com/ericlippert/2004/12/22/t4-vbscript-and-the-terminator/
另外
CPU是基于堆栈的计算机(而VBScript是基于堆栈的虚拟机)。当CPU调用一个函数时,调用程序将参数放在堆栈和返回地址上,调整堆栈帧并进行跳转。 callee函数在堆栈上创建局部变量,并将返回值放在其上。当它返回时,堆栈指针被调回到它自动释放所有上述内容的位置。