Kami mengalami masalah kehabisan memori setelah menginstal KB4525236 pada Klien Windows 2016 Server / Windows 10 kami. Perbaikan keamanan ini tampaknya telah mengubah saat ketika memori dikumpulkan ketika memanggil suatu fungsi GetRef
.
Pra KB4525236
Setiap instance dibuat dalam fungsi yang dipanggil melalui GetRef
sampah yang dikumpulkan segera setelah variabel instance diatur kenothing
Poskan KB4525236
Setiap instance dibuat dalam fungsi yang dipanggil GetRef
tetap dalam memori dan sampah dikumpulkan hanya ketika seluruh fungsi selesai . Saat membuat instance dalam satu loop, ini dapat dengan cepat bertambah dan menyebabkan kehabisan memori, terutama dalam proses 32-bit.
Pertanyaan
- kami tidak dapat menemukan sesuatu yang relevan secara online sehingga kami ingin mendapatkan konfirmasi dari orang lain yang mengalami masalah yang sama.
EDIT menggaruk bahwa: ini adalah masalah yang sama tetapi belum ada solusi
(bug class_terminate vbscript.dll sejak KB4524570 (12 November 2019) Windows 10 1903) - jika ada yang bisa memverifikasi dan mengetahui solusi yang bisa diterapkan, itu akan luar biasa.
POC
skrip berikut berjalan pada perangkat dengan KB4525236 diinstal menunjukkan perbedaan dalam pengumpulan sampah saat
- dipanggil langsung: instance kedua dibuat hanya setelah instance pertama dihancurkan (ini adalah perilaku yang kita inginkan)
- dipanggil melalui
GetRef
: instance kedua akan dibuat sebelum instance pertama dihancurkan sehingga ia memiliki dua instance menggunakan memori.
simpan sebagai: KB4525236.vbs
dijalankan sebagai: 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
sumber
GetRef()
tidak mengumpulkan sampah sampaiGetRef()
selesai. Itu berbeda dengan apa itu. Kami memiliki fungsi yang dipanggil melaluiGetRef()
pembuatan 1000 instance dan tetap menyimpan memori hinggaGetRef()
berakhir sementara di masa lalu, mereka dibebaskan saat menjalankan loopGetRef()
.With New IDummyInstance : End With
blok masih menghasilkan "Inisialisasi Instance Pertama, Inisialisasi Instance Kedua, Hentikan Instance Pertama, Hentikan Instance Kedua". Ini sangat salah, harus dilaporkan. Terlepas dari konsumsi memori, itu benar-benar merusak ini .Jawaban:
Karena saya tidak punya solusi atau sumber resmi yang menjelaskan masalah ini, saya sedang menunggu hadiah berakhir.
Saya telah menemukan solusi yang tidak menyenangkan yang dapat membantu sampai bug diperbaiki.
Solusinya adalah tidak menggunakan variabel lokal untuk menyimpan instance objek dalam prosedur yang dapat dieksekusi melalui
GetRef
.Alih-alih variabel implisit atau eksplisit, menggunakan objek kamus lokal (atau global jika tidak ada rekursi) untuk menyimpan instance objek dan memanggil mereka melalui kamus tersebut berfungsi.
Tampaknya layak digunakan jika Anda memiliki skrip yang tidak terlalu rumit.
sumber