c# - visual - ¿Cómo forzar la recolección de basura del objeto que no puede desreferenciar?
tooltip c# (2)
Estamos utilizando EWS Managed API, que sondea MS Exchange para nuevos mensajes de correo después de un intervalo determinado. Con cada invocación de la llamada de sondeo ( PullSubscription.GetEvents()
), la API de Microsofts falla al eliminar correctamente el NetworkStream
y hace que la memoria aumente proporcionalmente. Esto fue discutido previamente aquí , pero nunca se resolvió. Utilizando ANTS Profiler pudimos determinar qué objetos crecían continuamente en la memoria y aislar el problema.
Ahora que se ha aislado el problema, ¿hay alguna manera de deshacerse de un NetworkStream creado en una API externa a la que no tenemos referencia? GC.Collect () no parece disponer de él ya que todavía tiene una referencia activa. ¿Qué podemos hacer para limpiar la referencia colgante? ¿Hay algún contenedor que podamos usar para forzar la limpieza de su buggy SDK?
¡No hay forma de obligar a GC a liberar memoria para un objeto al que se hace referencia!
Antes que nada, sugeriría que contactasen a Microsoft para obtener ayuda con este error.
En segundo lugar, ¿estás hablando de "eliminación" o simplemente de liberación de memoria? Son dos cosas totalmente diferentes. (Patrón IDisposable, finalizadores).
En tercer lugar, ¿puede desreferenciar el objeto que hace referencia a estos objetos?
En cuarto lugar, una posible solución puede ser descompilar con reflector el código que le está dando el problema, comprender cómo puede llegar a los campos que mantienen los objetos referenciados, usar la reflexión en el código para acceder a los campos privados y colocarlos en nulo. Es un truco muy sucio, pero si no tienes otro camino es lo único que se me ocurre. Haz esto solo si no puedes ir de otras maneras.
La forma más sencilla sería ejecutar la parte que está interconectando el SDK en su propio AppDomain
y, una vez que haya terminado, descargue el AppDomain. Esto hará que se libere toda la memoria asignada en AppDomain.
Pero necesitará agregar algo de trabajo a su proyecto, ya que solo puede intercambiar con un MarshalByRef
objeto MarshalByRef
o marcarse como serilizable
.
Esto también le permitirá controlar la cantidad de memoria consumida por AppDomain. Para que pueda crear su AppDomain, ejecute el SDK defectuoso y, si alcanza un límite especial de consumo de memoria, puede descargarlo.