Memory management GetRef';的内存消耗(垃圾回收)已更改为KB4525236

Memory management GetRef';的内存消耗(垃圾回收)已更改为KB4525236,memory-management,vbscript,null,garbage-collection,reference-type,Memory Management,Vbscript,Null,Garbage Collection,Reference Type,在Windows 2016服务器/Windows 10客户端上安装后,我们遇到内存不足问题。当通过GetRef调用函数时,此安全修复程序似乎改变了内存被垃圾收集的时刻 PréKB4525236 在通过GetRef调用的函数中创建的每个实例在实例变量设置为nothing时都会被垃圾回收 邮政编码KB4525236 在通过GetRef调用的函数中创建的每个实例都保留在内存中,只有在整个函数完成时才会进行垃圾收集。在循环中创建实例时,这可能会快速累积并导致内存不足,特别是在32位进程中 问题 我们无

在Windows 2016服务器/Windows 10客户端上安装后,我们遇到内存不足问题。当通过
GetRef
调用函数时,此安全修复程序似乎改变了内存被垃圾收集的时刻

PréKB4525236 在通过
GetRef
调用的函数中创建的每个实例在实例变量设置为
nothing
时都会被垃圾回收

邮政编码KB4525236 在通过
GetRef
调用的函数中创建的每个实例都保留在内存中,只有在整个函数完成时才会进行垃圾收集。在循环中创建实例时,这可能会快速累积并导致内存不足,特别是在32位进程中

问题
  • 我们无法在网上找到任何相关信息,因此我们希望得到其他遇到相同问题的人的确认。
    编辑删除:是同一个问题,但到目前为止还没有解决方案
    (vbscript.dll类_终止自KB4524570(2019年11月12日)Windows 10 1903以来的错误)
  • 如果有人能够验证并知道一个可行的解决方案,那就太棒了
POC 在安装了KB4525236的设备上运行的以下脚本显示了在

  • 直接调用:只有在第一个实例被销毁后才能创建第二个实例(这是我们想要的行为)
  • 通过
    GetRef
    调用:在销毁第一个实例之前创建第二个实例,因此我们有两个使用内存的实例
另存为:KB4525236.vbs
运行方式:wscript KB4525236.vbs


由于我没有一个解决方案或官方消息来源来解释这个问题,我一直在等待悬赏期满

我已经想出了一个令人不快的解决方法,可以帮助直到错误被修复

解决方法是不使用任何局部变量来保存可能通过
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

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

@Lankymart-问题是在
GetRef()
中创建的实例在
GetRef()
结束之前不会被垃圾收集。那跟以前不一样。我们通过
GetRef()
调用函数,创建1000个实例,它们不断累积内存,直到
GetRef()
结束,而在过去,它们是在
GetRef()
中执行循环时释放的。感谢您的澄清,我不确定您将如何处理该tbh。想象一下,如果有人知道,那将是@eric lippert,因为他们在构建VBScript的原始团队中工作。我有你在没有KB4525236或KB4524570的Windows 7上描述的行为(显然还有另一个KB对Windows 7这么做)。不过,VBScript中没有垃圾收集,当对象的引用计数降至零时,对象将被销毁。如果没有发生这种情况,这是一个引擎错误,而不是GC运行的另一种方式。即使没有显式变量,情况也是如此。两个带有新IDummyInstance的
:End With
块仍会生成“初始化第一个实例、初始化第二个实例、终止第一个实例、终止第二个实例”。这是非常错误的,应该报告。除了消耗内存之外,它完全崩溃了。@Gserg-谢谢。至少,让我开心了;)刚刚测试过,我可以确认它在我的机器上工作。我将把这个标记为解决方案。在微软提供修复之前,这是最好的(假设他们承认这是一个bug)。
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