GetRef 的内存消耗(垃圾收集)随 KB4525236 改变

Lie*_*ers 13 vbscript null garbage-collection memory-management reference-type

在我们的 Windows 2016 服务器/Windows 10 客户端上安装KB4525236后,我们遇到了内存不足问题。此安全修复程序似乎已经改变了通过GetRef.

预 KB4525236

在通过GetRef将实例变量设置为垃圾收集器调用的函数中创建的每个实例nothing

发布 KB4525236

在调用 through 的函数中创建的每个实例都GetRef保留在内存中,并且只有在整个函数完成时才会垃圾回收。在循环中创建实例时,这会快速累加并导致内存不足,尤其是在 32 位进程中。

问题

  • 我们在网上找不到任何相关内容,因此我们希望得到遇到相同问题的其他人的确认。
    编辑从头开始:是相同的问题,但目前还没有解决方案
    (自 KB4524570(2019 年 11 月 12 日)Windows 10 1903 以来的 vbscript.dll class_terminate 错误)
  • 如果有人可以验证并知道可行的解决方案,那就太棒了。

POC

在安装了 KB4525236 的设备上运行的以下脚本显示了垃圾收集的不同之处

  • 直接调用:只有第一个实例被销毁才会创建第二个实例(这是我们想要的行为)
  • 通过调用GetRef:在销毁第一个实例之前创建第二个实例,因此有两个实例使用内存。

另存为:KB4525236.vbs
运行为:wscript KB4525236.vbs

Dim Name, Log

Class IDummyInstance
  Dim FName
  Sub Class_Initialize
    FName = Name
    Log = Log & "Initialize " & FName & VbNewLine
  End Sub
  Sub Class_Terminate
    Log = Log & "Terminate " & FName & vbNewLine
  End Sub
End Class

Sub CreateDestroyTwoInstances
  Dim DummyInstance
  Name = "First Instance"
  Set DummyInstance = New IDummyInstance
  Set DummyInstance = Nothing
  Name = "Second Instance"
  Set DummyInstance = New IDummyInstance
  Set DummyInstance = Nothing
End Sub

Log = "(1) Direct Call :" & VbNewLine
Call CreateDestroyTwoInstances

Log = VbNewLine & Log & "(2) GetRef Call :" & vbNewLine
Set GetRefCall = GetRef ("CreateDestroyTwoInstances")
Call GetRefCall

MsgBox Log
Run Code Online (Sandbox Code Playgroud)

Kul*_*gin 5

由于我没有解决方案或解释该问题的官方消息来源,我正在等待赏金到期。

我想出了一个令人不快的解决方法,可以在错误修复之前有所帮助。

解决方法是不使用任何局部变量来保存可能通过 执行的过程中的对象实例GetRef

使用本地(或全局,如果没有递归)字典对象来保存对象实例并通过该字典调用它们,而不是隐式或显式变量。

Sub CreateDestroyTwoInstances
  Dim Refs
  Set Refs = CreateObject("Scripting.Dictionary")
  Name = "First Instance"
  Refs.Add "DummyInstance", New IDummyInstance
  ' Call Refs("DummyInstance").DoSomething()
  Refs.Remove "DummyInstance"
  Name = "Second Instance"
  Refs.Add "DummyInstance", New IDummyInstance
  ' Call Refs("DummyInstance").DoSomething()
  Refs.Remove "DummyInstance"
End Sub
Run Code Online (Sandbox Code Playgroud)

如果您的脚本不太复杂,那么它似乎值得使用。

  • 刚刚测试过,我可以确认它可以在我的机器上运行。我将把它标记为解决方案。在微软提供修复之前,这是最好的*(假设他们承认这是一个错误)*。 (4认同)

Ian*_*tes 4

很好的问题。我是通过 Microsoft 论坛帖子找到的

https://answers.microsoft.com/en-us/windows/forum/all/vbscriptdll-classterminate-bug-since-kb4524570/1b34d9b4-91ce-4d61-a05c-1bfa0ec96344?auth=1

此 SO 的提问者添加了一个指向上面 Microsoft 线程的链接。

KB5005101 的发行说明中引用了该 Microsoft 线程(对于 Windows 10 21H1 - 其他 Windows 10 版本也会有类似的 KB)。链接到 Microsoft 发行说明: https://support.microsoft.com/en-us/topic/september-1-2021-kb5005101-os-builds-19041-1202-19042-1202-and-19043-1202-preview -82a50f27-a56f-4212-96ce-1554e8058dc1

微软声称已经解决了这个问题 Addresses a memory leak that occurs when you use nested classes within VBScript. 。在发行说明中,VBScript末尾的词是指向该微软论坛主题的超链接。比较微妙...

无论如何,虽然我不是 VBScript 的频繁用户,但作为一个长期的 COM 用户,以及对此类问题感兴趣的读者,我想一旦每个人都获得了每月的补丁,我会分享最终应该是最终的答案。 。这些发行说明只能追溯到 Windows 10 2004 年,因此 1909 年及更早版本可能不太走运,受此影响的 Windows 7 用户也可能不走运。