私たちは、インストール後に、メモリ不足の問題が発生したKB4525236を当社のWindows 2016サーバ/ Windowsの10クライアントで。このセキュリティ修正は、メモリが通過関数を呼び出すときにガベージコレクションによって収集された瞬間を変更しているようですGetRef
。
前KB4525236
呼び出された関数で作成された各インスタンスGetRef
得たごみはすぐにインスタンス変数に設定されたとして収集しましたnothing
ポストKB4525236
機能で作成された各インスタンスは、通過と呼ばれるGetRef
メモリにとどまり、あるゴミは場合にのみ、関数全体の完了を収集しました。ループ内のインスタンスを作成する場合、これはすぐに追加することができ、特に32ビットプロセスでは、メモリ不足につながります。
質問
- 私たちは同じ問題が発生して他の人からの確認を取得したいと思いので、我々は、オンライン関連する何かを見つけることができません。
編集:というスクラッチ、これは同じ問題が、まだのようがない溶液である
(1903年KB4524570(2019年11月12日以来のVbscript.dll class_terminateバグ)は、Windows 10) - 誰が確認し、可能な解決策を知っていることができれば、それは素晴らしいだろう。
POC
KB4525236を持つデバイス上で実行されている次のスクリプトは、ショーにガベージコレクションの違いを設置しました
- 直接呼び出さ:番目のインスタンスにのみ作成された後、最初のインスタンスが破棄される(これは私たちの希望の動作です)
- 経由で呼び出さ
GetRef
:番目のインスタンスが作成される前に、最初のインスタンスが破棄されたメモリを使用して2つのインスタンスを持っているWHEそう。
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
私は解決策や課題を説明する公式のソースを持っていないので、私が期限切れに恵みを待っていました。
私は、バグが修正されるまで助けることができる不快な回避策を作ってみました。
この問題を回避するには、を介して実行されるかもしれない手順でホールド・オブジェクト・インスタンスに任意のローカル変数を使用しないことです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
あなたがあまりにも複雑ではないスクリプトを持っている場合は使用しての価値があると思われます。