Problemy z brakiem pamięci występują po zainstalowaniu KB4525236 na naszych serwerach / klientach z systemem Windows 10. Wydaje się, że ta poprawka zabezpieczeń zmieniła się w momencie, gdy pamięć jest zbierana podczas wywoływania funkcji GetRef
.
Pre KB4525236
Każde wystąpienie utworzone w funkcji wywoływanej przez GetRef
zostało pobrane śmieci, gdy tylko zmienna wystąpienia została ustawiona nanothing
Opublikuj KB4525236
Każde wystąpienie utworzone w funkcji wywoływanej przez GetRef
pozostaje w pamięci i jest usuwane w pamięci tylko po zakończeniu całej funkcji . Podczas tworzenia instancji w pętli może to szybko zsumować się i doprowadzić do braku pamięci, szczególnie w procesie 32-bitowym.
pytania
- nie możemy znaleźć niczego istotnego w Internecie, dlatego chcielibyśmy uzyskać potwierdzenie od innych osób mających ten sam problem.
EDYCJA podstaw: to ten sam problem, ale na razie brak rozwiązania
(błąd vbscript.dll class_terminate od KB4524570 (12 listopada 2019 r.) Windows 10 1903) - jeśli ktokolwiek może zweryfikować i zna realne rozwiązanie, byłoby świetnie.
POC
poniższy skrypt działający na urządzeniu z zainstalowaną wersją KB4525236 pokazuje różnicę w zbieraniu pamięci, kiedy
- wywoływane bezpośrednio: druga instancja jest tworzona dopiero po zniszczeniu pierwszej instancji (jest to nasze pożądane zachowanie)
- wywoływane przez
GetRef
: druga instancja jest tworzona przed zniszczeniem pierwszej instancji, więc dwie instancje używają pamięci.
zapisz jako: KB4525236.vbs
uruchom jako: 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
źródło
GetRef()
nie pobierają śmieci doGetRef()
końca. To różni się od tego, co to było. Mamy funkcje wywoływane przezGetRef()
tworzenie 1000 wystąpień, które gromadzą pamięć aż doGetRef()
końca, podczas gdy w przeszłości były uwalniane podczas wykonywania pętliGetRef()
.With New IDummyInstance : End With
bloki nadal generują „Zainicjuj pierwszą instancję, Zainicjuj drugą instancję, Zakończ pierwszą instancję, Zakończ drugą instancję”. To bardzo źle, należy to zgłosić. Oprócz rzeczy, zużycie pamięci, to całkowicie łamie to .Odpowiedzi:
Ponieważ nie mam rozwiązania ani oficjalnego źródła wyjaśniającego problem, czekałem na wygraną.
Wymyśliłem nieprzyjemne obejście, które może pomóc, dopóki błąd nie zostanie naprawiony.
Obejściem tego problemu jest nieużywanie żadnej zmiennej lokalnej do przechowywania instancji obiektów w procedurach, które można wykonać
GetRef
.Zamiast zmiennych niejawnych lub jawnych, użycie lokalnego obiektu słownika (lub globalnego, jeśli nie ma rekurencji) do przechowywania instancji obiektów i wywoływanie ich przez ten słownik działa.
Wydaje się, że warto używać, jeśli masz skrypt, który nie jest zbyt skomplikowany.
źródło