Der Speicherverbrauch von GetRef (Garbage Collection) wurde mit KB4525236 geändert

11

Nach der Installation von KB4525236 auf unseren Windows 2016-Servern / Windows 10-Clients treten Probleme mit zu wenig Arbeitsspeicher auf. Diese Sicherheitskorrektur scheint sich in dem Moment geändert zu haben, in dem beim Aufrufen einer Funktion Speicherplatz gesammelt wird GetRef.

Pré KB4525236

Jede Instanz, die in einer durch aufgerufenen Funktion erstellt wurde, GetRefhat Müll gesammelt, sobald die Instanzvariable auf gesetzt wurdenothing

Beitrag KB4525236

Jede Instanz, die in einer durch aufgerufenen Funktion erstellt wurde, GetRefverbleibt im Speicher und wird erst nach Abschluss der gesamten Funktion als Müll gesammelt . Wenn Sie Instanzen in einer Schleife erstellen, kann sich dies schnell summieren und zu einem Speichermangel führen, insbesondere bei einem 32-Bit-Prozess.

Fragen

  • Wir können online nichts Relevantes finden und möchten daher eine Bestätigung von anderen erhalten, bei denen das gleiche Problem auftritt.
    EDIT kratz das: Dies ist das gleiche Problem, aber noch keine Lösung
    (vbscript.dll class_terminate Fehler seit KB4524570 (12. November 2019) Windows 10 1903)
  • Wenn jemand eine praktikable Lösung überprüfen kann und kennt, wäre das großartig.

POC

Das folgende Skript, das auf einem Gerät mit installiertem KB4525236 ausgeführt wird, zeigt den Unterschied bei der Speicherbereinigung, wenn

  • Direkt aufgerufen: Die zweite Instanz wird erst erstellt, nachdem die erste Instanz zerstört wurde (dies ist unser gewünschtes Verhalten).
  • genannt durch GetRef: die zweite Instanz erstellt wird , bevor die erste Instanz zerstört wird , so WHE hat Speicher mit zwei Instanzen.

Speichern unter: KB4525236.vbs wird
ausgeführt als: 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
Lieven Keersmaekers
quelle
1
@Lankymart - Das Problem ist, dass die in erstellten Instanzen GetRef()erst am GetRef()Ende Müll sammeln . Das ist anders als es war. Wir haben Funktionen, die durch das GetRef()Erstellen von Tausenden von Instanzen aufgerufen werden , und sie kumulieren den Speicher bis zum GetRef()Ende, während sie in der Vergangenheit beim Ausführen der Schleife freigegeben wurden GetRef().
Lieven Keersmaekers
1
Vielen Dank für die Klarstellung, ich bin mir nicht sicher, was Sie dagegen tun können. Stellen Sie sich vor, wenn jemand weiß, dass es @ eric-lippert sein wird, während er an dem ursprünglichen Team gearbeitet hat, das VBScript erstellt hat.
Lankymart
2
Ich habe das Verhalten, das Sie unter Windows 7 ohne KB4525236 oder KB4524570 beschreiben (anscheinend gibt es eine andere KB, die dies mit Windows 7 macht). Es gibt jedoch keine Speicherbereinigung in VBScript. Die Objekte müssen zerstört werden, wenn ihre Referenzanzahl auf Null fällt. Wenn dies nicht der Fall ist, handelt es sich eher um einen Motorfehler als um eine andere Art der GC-Funktion.
GSerg
2
Dies ist auch ohne explizite Variablen der Fall. Zwei With New IDummyInstance : End WithBlöcke erzeugen weiterhin "Erste Instanz initialisieren, Zweite Instanz initialisieren, Erste Instanz beenden, Zweite Instanz beenden". Dies ist sehr falsch, sollte gemeldet werden. Neben dem Speicherverbrauch Sache, es bricht völlig dies .
GSerg
1
@GSerg - Haben Sie zufällig einen Kanal, um dies zu melden? Nichts kommt schneller zu mir, als herauszufinden, wo Probleme gemeldet werden sollen. Diese Support-Seite führt zum Beispiel zu dieser Support-Seite, die effektiv zu nichts führt.
Lieven Keersmaekers

Antworten:

1

Da ich keine Lösung oder offizielle Quelle habe, die das Problem erklärt, habe ich darauf gewartet, dass das Kopfgeld abläuft.

Ich habe mir eine unangenehme Problemumgehung ausgedacht, die helfen kann, bis der Fehler behoben ist.

Die Problemumgehung besteht darin, keine lokale Variable zum Speichern von Objektinstanzen in Prozeduren zu verwenden, die möglicherweise ausgeführt werden GetRef.

Anstelle von impliziten oder expliziten Variablen funktioniert die Verwendung eines lokalen (oder globalen, wenn es keine Rekursion gibt) Wörterbuchobjekts zum Speichern von Objektinstanzen und zum Aufrufen über dieses Wörterbuch.

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

Es scheint sich zu lohnen, wenn Sie ein Skript haben, das nicht zu kompliziert ist.

Kul-Tigin
quelle
1
Ich habe es gerade getestet und kann bestätigen, dass es auf meinem Computer funktioniert. Ich werde dies als Lösung markieren. Es ist das Beste, bis Microsoft eine Lösung bereitstellt (vorausgesetzt, sie erkennen an, dass dies ein Fehler ist) .
Lieven Keersmaekers