Nous rencontrons des problèmes de mémoire insuffisante après l'installation de KB4525236 sur nos serveurs Windows 2016 / clients Windows 10. Ce correctif de sécurité semble avoir changé le moment où la mémoire est récupérée lors de l'appel d'une fonction via GetRef
.
Pré KB4525236
Chaque instance créée dans une fonction appelée via GetRef
récupère les ordures dès que la variable d'instance est définie surnothing
Message KB4525236
Chaque instance créée dans une fonction appelée via GetRef
reste en mémoire et n'est récupérée que lorsque la fonction entière est terminée . Lors de la création d'instances dans une boucle, cela peut rapidement s'accumuler et entraîner une mémoire insuffisante, en particulier dans un processus 32 bits.
Des questions
- nous ne trouvons rien de pertinent en ligne, nous aimerions donc obtenir la confirmation d'autres personnes rencontrant le même problème.
EDIT rien que: c'est le même problème , mais sans solution pour l'instant (bug vbscript.dll Class_Terminate depuis KB4524570 (12 Novembre, 2019) de Windows 10 1903)
- si quelqu'un peut vérifier et connaît une solution viable, ce serait génial.
POC
Le script suivant exécuté sur un appareil sur lequel KB4525236 est installé montre la différence de collecte des ordures lorsque
- appelé directement: la deuxième instance n'est créée qu'après la destruction de la première instance (c'est notre comportement souhaité)
- appelé à travers
GetRef
: la deuxième instance est créée avant la première instance est détruite donc nous avons deux instances utilisant de la mémoire.
enregistrer sous: KB4525236.vbs
exécuter comme: 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
la source
GetRef()
ne sont pas récupérées jusqu'à laGetRef()
fin. C'est différent de ce que c'était. Nous avons des fonctions appelées enGetRef()
créant des milliers d'instances et elles continuent de cumuler la mémoire jusqu'à laGetRef()
fin tandis que dans le passé, elles ont été libérées lors de l'exécution de la boucleGetRef()
.With New IDummyInstance : End With
blocs produisent toujours "Initialize First Instance, Initialize Second Instance, Terminate First Instance, Terminate Second Instance". C'est très faux, il faut le signaler. En dehors de la consommation de mémoire, cela casse complètement cela .Réponses:
Comme je n'ai pas de solution ou de source officielle expliquant le problème, j'attendais que la prime expire.
J'ai trouvé une solution de contournement désagréable qui peut aider jusqu'à ce que le bug soit corrigé.
La solution de contournement consiste à ne pas utiliser de variable locale pour conserver les instances d'objet dans les procédures qui pourraient être exécutées
GetRef
.Au lieu de variables implicites ou explicites, l'utilisation d'un objet de dictionnaire local (ou global s'il n'y a pas de récursivité) pour contenir les instances d'objet et les appeler via ce dictionnaire fonctionne.
Cela semble valoir la peine d'être utilisé si vous avez un script qui n'est pas trop compliqué.
la source