Experimentamos problemas de falta de memoria después de instalar KB4525236 en nuestros servidores Windows 2016 / Clientes Windows 10. Esta solución de seguridad parece haber cambiado en el momento en que se recolecta basura en la memoria cuando se llama a una función GetRef
.
Pré KB4525236
Cada instancia creada en una función llamada GetRef
se recogió basura tan pronto como la variable de instancia se estableció ennothing
Publicar KB4525236
Cada instancia creada en una función llamada a través GetRef
permanece en la memoria y se recolecta basura solo cuando se completa toda la función . Al crear instancias en un bucle, esto puede sumar rápidamente y conducir a una falta de memoria, especialmente en un proceso de 32 bits.
Preguntas
- no podemos encontrar nada relevante en línea, por lo que nos gustaría obtener la confirmación de otras personas que experimentan el mismo problema.
EDITAR tachar eso: este es el mismo problema pero aún no tiene solución
(error vbscript.dll class_terminate desde KB4524570 (12 de noviembre de 2019) Windows 10 1903) - si alguien puede verificar y conoce una solución viable, sería genial.
POC
El siguiente script que se ejecuta en un dispositivo con KB4525236 instalado muestra la diferencia en la recolección de basura cuando
- llamado directamente: la segunda instancia se crea solo después de que se destruye la primera instancia (este es nuestro comportamiento deseado)
- llamado
GetRef
: la segunda instancia se crea antes de que se destruya la primera instancia, por lo que hay dos instancias que usan memoria.
guardar como: KB4525236.vbs
ejecutar como: 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
fuente
GetRef()
no se recolectan hasta queGetRef()
finaliza. Eso es diferente a lo que era. Tenemos funciones llamadas a través de laGetRef()
creación de miles de instancias y siguen acumulando memoria hasta elGetRef()
final, mientras que en el pasado, se liberaron al ejecutar el bucleGetRef()
.With New IDummyInstance : End With
bloques aún producen "Inicializar primera instancia, Inicializar segunda instancia, Terminar primera instancia, Terminar segunda instancia". Esto está muy mal, debe informarse. Aparte del consumo de memoria, rompe completamente esto .Respuestas:
Como no tengo una solución o una fuente oficial que explique el problema, estaba esperando que expirara la recompensa.
Se me ocurrió una solución desagradable que puede ayudar hasta que se solucione el error.
La solución alternativa es no utilizar ninguna variable local para contener instancias de objetos en procedimientos que podrían ejecutarse a través de
GetRef
.En lugar de variables implícitas o explícitas, usar un objeto de diccionario local (o global si no hay recursividad) para contener instancias de objetos y llamarlas a través de ese diccionario funciona.
Parece que vale la pena usarlo si tiene un script que no es demasiado complicado.
fuente