significado significa reservadas que programacion palabras lenguaje identificadores con claves c# .net memory memory-leaks profiling

significa - Liberación explícita de memoria en c#



palabras reservadas en programacion y su significado (9)

He creado una aplicación de CA # que utiliza hasta 150 MB de memoria (bytes privados), principalmente debido a un gran diccionario:

Dictionary<string, int> Txns = new Dictionary<string, int>();

Me preguntaba cómo liberar esta memoria. He intentado esto:

Txns = null; GC.Collect();

Pero no parece hacer mucho mella en mis bytes privados: caen de, por ejemplo, 155 mb a 145 mb. ¿Alguna pista?

Gracias

-editar-

De acuerdo, tengo más suerte con este código (los bytes privados bajan a 50mb), pero ¿por qué?

Txns.Clear(); // <- makes all the difference Txns = null; GC.Collect();

-editar-

Está bien para todos los que dicen "no usen GC.collect", es justo (no voy a debatir eso, aparte de decir que pueden ver mi historial de C llegando), pero realmente no responde mi pregunta: ¿Por qué el recolector de basura solo libera la memoria si borro primero la lista de transacciones? ¿No debería liberar la memoria de todos modos, ya que el diccionario ha sido desreferenciado?


¿Necesitas recuperar la memoria? La memoria está disponible, simplemente no está siendo reclamada. No debe borrar el diccionario, mantener una referencia débil y dejar que el tiempo de ejecución haga su trabajo.

Si quiere ver realmente lo que está pasando, consulte .NET Memory Profiler . Eso le dará visibilidad sobre qué está sucediendo exactamente con su objeto, qué generación es, qué memoria está siendo utilizada por qué, y así sucesivamente. :)


Editar:

Para ser justos, establecer la referencia a null no libera la memoria, sino que asigna su contenedor a una dirección diferente, en este caso nula. Según MSDN , al llamar a Clear() , hace esto: "La propiedad Count se establece en 0 y también se lanzan referencias a otros objetos de elementos de la colección. La capacidad permanece sin cambios".

...

Nunca debes llamar al recolector de basura. Está utilizando objetos administrados sin recursos nativos, confíe en el recolector de elementos no utilizados para limpiarlos después de usted.

Además del tamaño de su diccionario, no necesita preocuparse por la memoria, la memoria no es su problema, es un problema para los recolectores de basura.

Llamar a Clear() eliminará las referencias a cualquier objeto contenido dentro, pero la capacidad permanece sin cambios.

En una nota técnica, la recolección de memoria es costosa y consume mucho tiempo. Por lo que respecta a la razón, el GC no solo maneja la memoria del montón y limpia su montón, sino que también desfragma el montón. Intenta mover la memoria a bloques contiguos para acelerar la asignación para cuando algún fragmento de código haga una solicitud grande.

ps ¿Qué tan grande es su diccionario que usa 155MB de memoria?


Generalmente no es una buena idea intentar forzar el GC. ¿De verdad necesitas tener todo el diccionario en la memoria?


Lo más probable es que tengas una referencia oculta al diccionario en otro lugar. Por lo tanto, el diccionario no se recopila, pero si lo Clear() , los contenidos se recopilan.

Como otros ya han notado, no se recomienda forzar el GC. Esto podría llevar a que la memoria se introduzca en "generaciones" superiores que a menudo no se recopilan, desperdiciando así más memoria que la obtenida a largo plazo.


Los bytes privados reflejan el uso de la memoria del proceso. Cuando se recopilan objetos, el segmento de memoria asociado puede o no liberarse en el sistema operativo. El CLR administra la memoria en el nivel del sistema operativo y, como la asignación y liberación de la memoria no es gratuita, no hay razón para liberar cada parte de la memoria de inmediato ya que es probable que la aplicación solicite más memoria más adelante.


No estoy seguro de la memoria si Dictionary tiene un Dispose() o no, pero está obligado a tener un Clear() . Llame a cualquiera de estos antes de establecer cualquier referencia a null .

Entonces, simplemente deje que el recolector de basura haga su trabajo. Casi nunca es una buena idea llamar a GC.Collect() explícitamente usted mismo y es posible que ni siquiera haga lo que quiere / necesita / espera y le cueste rendimiento. El Análisis de Código Estático (= FxCop) no le advierte sobre la regla de Confiabilidad CA2001 sobre esto para nada, ¿sabe? Simplemente no hagas esto a menos que realmente sepas lo que estás haciendo. Y aun así no lo hagas. ;-)

¿Estás seguro de que el diccionario es tan grande? ¿No son solo 10 Mb de memoria y el resto es tomado por tu aplicación? Pregunta que podría ayudarlo: ¿ha utilizado un generador de perfiles para ver dónde se consume realmente la memoria ...?


Ok, tengo una teoría aquí ... Dictionary es una colección de KeyValuePair que es nuevamente un tipo de referencia.

Su diccionario contiene estos keyValuePairs. Cuando tu dices:

Txns = null

Libera la referencia ''Txns'' de la colección KeyValuePair. Pero aún la memoria real de 150 Mb está siendo referenciada por esos KeyValuePair y están dentro del alcance, por lo tanto, no están listos para la recolección de basura.

Pero cuando usas lo siguiente:

Txns.Clear(); Txns = null; GC.Collect();

Aquí, el método claro también libera los 150Mb de datos de sus respectivas referencias de objeto KeyValuePair. Por lo tanto, esos objetos estaban listos para la recolección de basura.

Es solo una conjetura salvaje que estoy haciendo aquí. Los comentarios son bienvenidos :)


Windows tiene dos eventos de disponibilidad de memoria. Esperaría que el CLR responda a esto. Si hay suficiente memoria disponible, lo más inteligente es NO ejecutar el recolector de basura. Por lo tanto, para asegurarse de que realmente está observando un mal comportamiento CLR, repita esta prueba con otra aplicación ficticia utilizando un gran montón de memoria.


si llama a GC.Collect (), comienza a hacer su trabajo, pero vuelve inmediatamente, no bloquea, por lo que no ve su efecto, si solo llama a GC.WaitForPendingFinalizers () después de eso, bloqueará su aplicación hasta que aparezca GC. Collect () termina su trabajo