2012-07-26 8 views
5

Acabo de comenzar con .NET Framework con C# como mi idioma. De alguna manera, entiendo el concepto de GC en Java, y hoy volví a visitar el mismo concepto en .NET.¿La recolección de basura alguna vez afecta la pila?

En C#, los tipos de valores se ponen en la pila (igual que en el caso de Java, donde las variables locales se ponen en la pila). Pero en C#, incluso struct está incluido en los tipos de valor. Por lo tanto, incluso struct s se colocan en la pila. En el peor de los casos, donde hay muchas llamadas a métodos, y la pila está llena de muchos métodos, y cada método tiene muchos tipos de valores locales, y muchos struct que tienen muchos tipos de valores locales, el recolector de basura afectará alguna vez ¿la pila? De lo que investigué (y en parte de lo que me enseñaron), entiendo que no lo hará. Principalmente porque la manipulación del contenido de la pila implicará una gran sobrecarga, y además, GC solo consulta la pila para buscar referencias, y nada más que eso.

Solo para agregar otra pregunta relacionada con el mismo tema: Forzar una llamada a GC (como System.gc() en Java, no estoy seguro del equivalente de C#), no garantiza que se llame a la rutina GC en ese momento. Entonces, ¿dónde debería hacer esa llamada? ¿Dónde espero que necesite la GC o cualquier lugar aleatorio ya que no hay garantía de que mi llamada active inmediatamente la GC? ¿O debería dejar las cosas en el entorno de tiempo de ejecución y no molestarme al respecto?

Nota: agregué la etiqueta Java porque estoy tratando de vincular conceptos desde allí. Entiendo que el funcionamiento interno de GC en los dos entornos de tiempo de ejecución por separado será definitivamente diferente, pero creo que el concepto subyacente sería el mismo.

Respuesta

2

No recolección de basura no afecta a los objetos en la pila de Java.

GC solo afecta objetos en el montón de jvm. El proceso de GC de Java tiene varios niveles y puede ser muy complejo, y vale la pena leerlo. Visite un sitio como: http://javarevisited.blogspot.com/2011/04/garbage-collection-in-java.html para obtener una buena idea de cómo funciona.

En cuanto a forzar el sistema GC es una mala idea. El jvm tendrá una mejor idea que cuando un GC necesita ejecutarse. Si está intentando asignar un objeto grande, el jvm se asegurará de que haya espacio para usted sin que tenga que decirle que ejecute el GC.

EDIT Mi mal, usted está más preocupado por C# que java. Se aplican los mismos principios de administración de memoria, la pila no se ve afectada, no ejecuta explícitamente un GC, etc. C# está diseñado para funcionar de manera similar a Java. http://msdn.microsoft.com/en-us/library/ms973837.aspx

+0

Gracias por responder. Volveré después de haber leído más sobre él. –

1

No. AFAIK GC no afecta a la pila. Solo afecta a la memoria HEAP. El marco de pila se creará con las llamadas a los métodos y se eliminará al salir del método.

EDITAR

Este MSDN article explica cómo funciona la GC en el marco .NET.

+0

¿funciona esto para Java, C# o ambos? –

+0

Esto es solo para JAVA. No sé mucho sobre C#, pero creo que C# sigue principios similares. – kosa

+0

Mi pregunta está en el contexto de C#, pero gracias por su respuesta. –

2

las pilas no necesitan la ayuda de un recolector de basura; porque, a medida que se mueve fuera de los marcos de pila (el alcance de la ejecución actual dentro de la pila), se libera (y se sobrescribe) todo el fotograma, incluidos los contenidos, a medida que crea un nuevo fotograma de pila.

function foo(int a, int b) { 
    int i; 
    doStuff(); 
} 

crea un marco de pila (visualización áspero)

---- Frame Start ---- 
(value for parameter a) 
(value for parameter b) 
(other items needed for tracking execution) 
(extra stack frame space 
    (value for stack allocated i) 
) 
---- End of Frame ---- 

Al introducir una función, apilar las variables asignados se asignan como se asigna el marco, al salir del marco, toda la trama se descarta, desasignar la memoria para variables asignadas marco

Tenga en cuenta que Java normalmente asigna referencias a objetos y acumula primitivas locales en la pila, no objetos enteros.Solo unas pocas optimizaciones recientes permiten la asignación dentro de la pila de objetos no alcanzables fuera del marco; que tiene tales condiciones que no se considera algo con lo que puedas contar.

Dicho esto, las referencias en el marco de la pila normalmente apuntan al montón, que es la recolección de basura normalmente.

+0

Entiendo el concepto de pila. Pero en el peor de los casos, había preguntado dónde se llena la pila con muchas llamadas a función (una función llamando al otro y así sucesivamente, donde en los otros marcos no salen de la pila). Pero de alguna manera ahora entiendo que no importa qué, la pila nunca se ve afectada. –

+1

Si se necesitan suficientes marcos de pila que sobrepasan la memoria asignada para el espacio de pila, los marcos no se mueven al montón. En cambio, se produce un error de acumulación de pila y el proceso se detiene. –

+0

Ojalá pudiera votarte más tu respuesta e incluso aceptarla, me gustó mucho porque me hiciste entender bien el escenario de la pila, y también me recordó la existencia de algo llamado stackoverflowerror. Pero la otra respuesta proporcionó una solución global. Gracias de todos modos. –

1

. La recolección de elementos no utilizados .NET se explica en profundidad en Garbage Collection en MSDN. El recolector de basura realiza un seguimiento de la memoria solo en el montón administrado.

Cuestiones relacionadas