2012-05-02 14 views
8

Un colega mío está convencido de que hay una pérdida de memoria en la implementación de Oracle odp.net ado.net. Ha escrito un programa de prueba para probar esta teoría y está haciendo lo siguiente después de llamar a disponer en cada objeto con el fin de determinar la cantidad de memoria que se está liberado:GC.Collect() y PerformanceCounter

PerformanceCounter p = new PerformanceCounter("Memory", "Available Bytes"); 

GC.Collect(); 
GC.WaitForPendingFinalizers(); 

float mem = p.NextValue(); 

El valor de rendimiento resultante se compara entonces con un valor recuperado antes de deshacerse del objeto. ¿Esto producirá resultados precisos?

+10

No, así funciona el administrador de memoria. Después de que se haya tomado la molestia de asignar espacio de memoria virtual, vuelve a colocar los bloques liberados en la lista de bloques libres, listos para volver a usarlos más tarde. –

+0

¿Ha intentado utilizar ProcessExplorer para controlar la memoria .NET y el uso de la memoria del sistema dentro de su proceso? No ha indicado qué tipo de memoria se está escapando ... – GregC

+0

No sabemos qué tipo de memoria está goteando, esa es parte del motivo de la prueba, para confirmar que hay un problema. Mi pregunta es para confirmar si la prueba es válida. – zaq

Respuesta

2

Creo que la mejor manera de hacerlo es usar GC.GetTotalMemory(true). Puede llamarlo antes de asignar el objeto para registrar cuánta memoria se asignó en ese momento. A continuación, cree su objeto, tal vez realice alguna operación en él, deséchelo, asegúrese de que no haya referencias (probablemente solo establezca la variable local en null) y luego llámelo de nuevo.

Tenga en fuerza que el valor devuelto puede no ser exacta y por la documentación, el método devolverá:

Número que es la mejor aproximación disponible del número de bytes actualmente asignado en memoria administrada .

Después de eso, puede comparar los dos valores. Si lo hace de forma repetida, puede ver si el objeto realmente está escapando de la memoria administrada.

Por supuesto, esto no lo ayudará si el objeto pierde la memoria no administrada.

Otra opción es utilizar un generador de perfiles de memoria, pero eso podría ser una exageración si sabe exactamente dónde se puede filtrar la memoria.

+0

Gracias por la idea de cómo obtener mejores resultados. ¿Esto significa que hay algo mal con el enfoque que publiqué? ¿Por qué es este un mejor enfoque? – zaq

+2

Sí, su enfoque es incorrecto, lea el comentario de Hans Passant. Cuando el CLR recoge basura, por lo general no devuelve la memoria al sistema, por lo que es posible que no vea ningún cambio en Bytes disponibles, aunque la memoria realmente se haya liberado. – svick

Cuestiones relacionadas