7

.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 与 cscript.exe 与任何 Web 主机引擎被调用)

  7. JScript 的对象破坏模型与 VBScript 的不同吗?

我可以凭经验找到其中一些问题的答案,但我对它们中的任何一个是否得到保证/记录感兴趣。

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

4

1 回答 1

11

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

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

Class_Terminate 将以什么顺序被调用?

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

粗略戳建议按创建的顺序(而不是相反的顺序!),但这是保证吗?

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

对象的类型重要吗?例如,如果我在.VBS 中实现了与其他COM 对象(如Scripting.FileSystemObject)混合的类。

它可以。在不可预测的时间被拆除的那些对象之间可能存在循环引用。

我正在考虑全局范围内的对象,当程序退出时 - 例如函数范围内的对象是否有所不同?

我不明白这个问题。你能澄清一下吗?

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

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

Windows Script Host 在调用 Quit 时会尝试彻底关闭引擎。

WScript 对象何时被销毁?

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

脚本宿主重要吗?(wscript.exe 与 cscript.exe 与任何 Web 主机引擎被调用)

是的,这很重要。

JScript 的对象破坏模型与 VBScript 的不同吗?

是的,非常如此。

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

IE 9 版本的 JScript 有一个完全重写的垃圾收集器,它使用了非常不同的技术;我和它的设计师聊了一会儿,但我没有足够的技术知识来深入讨论它的特性。

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

我能问一下你为什么关心这些东西吗?

另外,请注意,我已经十多年没有看过这段代码了。以适当的怀疑态度对待所有这些。我的记忆可能有问题。

于 2010-09-17T18:41:46.630 回答