VBScript中对象的破坏顺序是什么?

时间:2010-09-16 17:03:27

标签: windows vbscript destructor object-lifetime

.vbs中的对象以什么顺序销毁?

也就是说,给定这些全局变量:

Set x = New Xxx
Set y = New Yyy

我对以下任何的答案感兴趣。

  1. 对于.VBS中实现的类的实例,将调用Class_Terminate的顺序是什么?粗略的戳戳暗示了创造的顺序(逆序!),但这有保证吗?

    编辑:我了解在释放对象的最后一次引用时将调用Class_Terminate。我的意思是:x和y的发布顺序是什么,是否有保证?为简单起见,假设x& y是对其各自对象的唯一引用

  2. 对象的类型是否重要?例如如果我在.VBS中实现的类与其他COM对象混合在一起,例如Scripting.FileSystemObject

    编辑:我知道COM库可能会设置自己的内部循环引用,脚本主机引擎一无所知;我有兴趣探索可能影响第一个问题答案的内容。

  3. 上述不同的答案,如果x和y是Sub或Function的本地而不是全局?
  4. 是否取决于退出是正常,异常还是通过WScript.Quit? (在后一种情况下,似乎在退出之前仍会在任何未完成的对象上调用Class_Terminate,但这些可能会导致报告错误。)
  5. WScript对象何时销毁?
  6. 脚本主机是否重要? (wscript.exe vs cscript.exe与调用Web主机引擎无关)
  7. JScript的对象销毁模型与VBScript的不同吗?
  8. 我可以凭经验找到其中一些问题的答案,但我对其中是否有任何保证 /记录感兴趣。

    即使你只知道一些答案 - 或其他相关问题,也要发帖。

1 个答案:

答案 0 :(得分:9)

我在VBScript中设计并实现了这个功能。

大多数答案都在我的文章中,Mark引用,但只是为了澄清:

  

将以什么顺序调用Class_Terminate?

通常在释放对象的最后一个引用时立即调用终结符。但是,由于循环引用和其他问题,依赖确定性的终止顺序通常是一个非常糟糕的想法。

  

粗略的戳戳暗示了创造的顺序(不是逆序!),但这有保证吗?

正如我在文章中提到的,当发动机关闭时,未终止的对象会被终止。作为实现细节,终止队列按照创建对象的顺序执行。但是,这是一个您不应该依赖的未记录的实现细节。

  

对象的类型是否重要?例如如果我在.VBS中实现的类与其他COM对象混合在一起,例如Scripting.FileSystemObject。

它可以。在那些在不可预测的时间被拆除的物体中可能存在循环引用。

  

我正在考虑全局范围内的对象,当程序退出时 - 对于例如对象,它是不同的。功能范围?

我不明白这个问题。你能说清楚吗?

  

是否取决于退出是正常的,异常还是通过WScript.Quit? (在后一种情况下,似乎在退出之前仍会在任何未完成的对象上调用Class_Terminate,但是这些可能会导致报告错误。)

重要的是,是的。 VBScript不保证终结器始终运行。拥有引擎的主机可以通过“快速失败”以不能保证干净地关闭引擎的方式关闭其进程,例如。 (如果发生灾难性故障,这有时是可取的;如果你不知道什么是错的,那么有时运行终止代码会使问题变得更糟,而不是更好。)

Windows Script Host会在调用Quit时尝试干净地关闭引擎。

  

WScript对象何时销毁?

当Windows脚本宿主进程终止逻辑运行时。

  

脚本主机是否重要? (wscript.exe vs cscript.exe与调用Web主机引擎无关)

是的,这很重要。

  

JScript的对象销毁模型与VBScript的不同吗?

是的,非常如此。

JScript“Classic”从我工作的时期开始(2001年之前)使用了一个非确定性的标记和清除垃圾收集器,它在脚本对象中处理循环引用,但不处理脚本和浏览器对象之间的循环引用。更新版本的JScript“Classic”有一个修改过的垃圾收集器,它可以处理脚本和浏览器对象之间的循环引用(尽管它不一定能检测涉及JScript对象和第三方ActiveX对象的循环。)

IE 9的JScript版本有一个完全重写的垃圾收集器,它使用了截然不同的技术;我和它的设计师聊了一下,但我没有足够的技术知识来讨论它在任何深度上的特征。

JScript .NET当然使用CLR垃圾收集器。

我可以问你为什么关心这些东西吗?

另外,请注意我十多年来没有看过这段代码;以适当的怀疑态度来解决所有这些问题。我的记忆可能有问题。