c# - usar - ¿Dónde se almacenan todos los miembros estáticos?
metodos estaticos php (3)
Cada vez que se carga un proceso en la RAM, podemos decir que la memoria se divide aproximadamente en tres áreas (dentro de ese proceso): Stack, Heap y Static (que, en .NET, es en realidad un área especial dentro de Heap solo conocida como Heap de alta frecuencia).
La parte estática contiene las variables y métodos del miembro "estático". ¿Qué es exactamente estático? Aquellos métodos y variables que no necesitan una instancia de una clase para ser creados se definen como estáticos
Lea más here .
Esta pregunta ya tiene una respuesta aquí:
- ¿Cómo funcionan exactamente los campos estáticos? [duplicado] 11 respuestas
Estoy tratando de aprender cómo C # gestiona la memoria. Estoy atrapado en elementos estáticos, leo numerosos blogs y artículos sobre este tema, pero no puedo encontrar una respuesta bastante satisfactoria.
Definamos un bloque de código para ayudar a encontrar la respuesta.
class myClass
{
static string myStr = "String Data";
static int myInt = 12;
}
Antes de que ustedes compartan su respuesta, permítanme compartir mis hallazgos que sé sobre este tema. Siéntase libre de estar de acuerdo o en desacuerdo y ayudarme a encontrar la respuesta correcta.
- Static es solo para toda la vida.
- Un tipo de referencia estática (myStr), continuará en montón, para toda la vida.
- Un tipo de valor estático (myInt), irá a la pila, para toda la vida.
Lo que me confunde, son algunas respuestas que encontré en internet, sobre este tema.
Confusión número 1:
Cuando se inicia el programa, carga todos los ensamblados relacionados en un dominio de aplicación. Cuando se carga el ensamblaje, se invocan todos los constructores estáticos, incluidos los campos estáticos. Vivirán allí, y la única forma de descargarlos es descargar el AppDomain.
En líneas anteriores, se menciona explícitamente que todos los elementos estáticos almacenados en AppDomain. Entonces, ¿por qué todo el mundo en Internet dice que los elementos "Estáticos" se almacenan en montón / pila?
Confusión número 2:
Cada variable estática se almacena en el montón, independientemente de si está declarada dentro de un tipo de referencia o un tipo de valor.
Si cada variable estática almacenada en Heap. Entonces, ¿por qué algunas personas dicen que la variable estática de tipo de valor se almacena en la pila?
Por favor, ayuda a conectar mis puntos para comprender la administración de la memoria de las variables estáticas en C #. Muchas gracias por tu precioso tiempo :)
Hay una instancia de la clase creada, con todos los miembros estáticos inicializados.
Los miembros de las clases estáticas normalmente se almacenan en el montón, los miembros de los tipos de valores normalmente se almacenan en la pila.
Esto no tiene que ser el caso sin embargo, usted puede leer this blog para más información.
Es de uno de los diseñadores de lenguaje de C #, Eric Lippert.
El blog muestra que, al contrario del conocimiento normal, no está seguro de que los tipos de valores estén en la pila y los tipos de referencia estén en el montón, pero normalmente lo son.
Simplemente no está especificado en la especificación.
Primero, tenga en cuenta que todo esto es un detalle de implementación. Lo único que garantiza el tiempo de ejecución es:
- Cuando pides un campo estático, está ahí
- Un constructor estático se ejecuta en algún momento antes de usar el tipo
Eso es practicamente todo. Todo lo demás es un detalle de implementación: la especificación no se preocupa por la pila, el montón o cualquier otra cosa. Depende de la implementación del tiempo de ejecución, y un tiempo de ejecución válido podría poner todo en la pila, si así lo deseara, o en el montón. Y no te olvides de los registros.
Ahora, veamos algunos de los conceptos erróneos que ya lograste recoger:
- Static es solo para toda la vida , sí. No dice nada sobre cuándo ni dónde está almacenado, solo que está disponible cuando lo solicitó. Un tiempo de ejecución compatible es libre de usar cualquier memoria que desee, o incluso nunca cargar los campos en la memoria (por ejemplo, mantenerlo en la imagen, que ya está en la memoria de todos modos)
- Static continuará en montón, durante toda la vida , lo más probable es que sí. Pero no es parte de la especificación, y un tiempo de ejecución compatible puede almacenarlo donde quiera, o en ninguna parte, siempre y cuando se cumplan las garantías adecuadas. Además, no olvide que "para toda la vida" significa "al menos durante el tiempo de vida del AppDomain"; puede o no liberarse cuando el dominio está descargado.
- El tipo de valor estático irá a la pila, para toda la vida , lo más probable es que no. Nuevamente, un detalle de implementación, pero la pila tiene una semántica completamente diferente a la que tiene sentido para un valor estático. Y el próximo punto le dará más de una razón por la cual:
- Cuando se carga la asamblea, se invocan todos los constructores estáticos, incluidos los campos estáticos. - No. No hay tal requisito, ni tal garantía. Si confía en esto, su programa se romperá (y lo he visto muchas veces antes). Nuevamente, un detalle de implementación, pero en las implementaciones de MSCLR actuales, las estadísticas tienden a asignarse en un montón, y un poco antes de que se necesite el tipo en el que están definidas. Puede ver esto fácilmente si lanza una excepción en un constructor estático: causará una
TypeLoadException
, muy probablemente en un método que primero haga referencia al tipo (no hace falta decir que esto puede hacer que la depuración estética sea complicada). - Los tipos de referencia van en el montón, los tipos de valores van en la pila. - No. Esto confunde el mecanismo con la semántica. La única diferencia entre los dos es su semántica: todo lo demás depende de la implementación. Si un tiempo de ejecución puede conservar la semántica de referencia para los tipos de referencia en la pila, eso es perfectamente válido. E incluso con los tiempos de ejecución actuales de MSCLR, los tipos de valores se almacenan en el montón todo el tiempo, siempre que estén encuadrados, o miembros de un tipo de referencia, por ejemplo.
Algunas personas pueden estar confundidas. Algunos no entienden la diferencia entre el contrato y las implementaciones prácticas. Algunos simplemente no saben de lo que están hablando. Ojalá hubiera una manera fácil de saber cuál es cuál, pero no lo es. Si tiene dudas, puede ir a las especificaciones C # / CLR, pero eso solo le informa sobre el contrato, no sobre la realidad práctica.
El objetivo de la memoria administrada es que no debe preocuparse por estos detalles de implementación. Por supuesto, como cualquier abstracción, tiene fugas, y tiene sentido saber cómo son realmente las cosas, hasta las microinstrucciones de la CPU, el almacenamiento en memoria caché, etc., a través de todas las capas y abstracciones. Pero no hay nada de lo que depender : la implementación puede cambiar en cualquier momento, y lo ha hecho muchas veces en el pasado.