c# - usar - ¿Cómo funcionan exactamente los campos estáticos?
static programacion (11)
Esto depende completamente de la implementación en cuestión. Para C # y Java, el tiempo de ejecución permite determinar dónde almacenar la memoria para la variable. Para C y la mayoría de los lenguajes compilados, el compilador hace esta determinación.
Dicho esto, en la práctica, no importa . El uso lo determinó por especificación, por lo que puede usar la variable sabiendo que el comportamiento estará garantizado.
Esta pregunta ya tiene una respuesta aquí:
Digamos que tienes una clase,
class Foo
{
public static bar;
}
Cuando tu dices:
new Foo();
Puedo imaginar que en la memoria, un espacio está reservado para este objeto.
... y cuando vuelvas a decir:
new Foo();
... bueno, ahora tienes otro espacio disponible para el objeto.
Sin embargo, ¿dónde exactamente vive el campo estático?
Lo que estoy tratando de aprender es:
¿De qué manera las referencias a los objetos hacen referencia al mismo campo de los objetos a los que hacen referencia?
Esto depende del idioma al idioma o del diseñador del idioma. Si hablo de Java, los miembros estáticos se almacenan en el área Método de la JVM y todos los objetos están vinculados a ellos. Una cosa más que es muy importante saber es que podemos acceder al miembro de datos estáticos sin crear el objeto de la clase. Significa que la asignación de la memoria a los miembros de datos estáticos no depende de la creación del objeto de esa clase. clase.
Esto varía enormemente de un idioma a otro, e incluso puede variar de una plataforma a otra ...
Por ejemplo, en el lado de .NET, los miembros estáticos están "asociados" con la definición EEClass
gobernante, que puede ser asignada en un montón O un miembro asignado "donde sea" (la especificación C # no especifica el comportamiento de pila / montón, es un detalle de implementación de la VM)
Las variables estáticas pertenecen a la clase, no al objeto, por lo que solo hay una bar
en la memoria, incluso si inicializa miles de instantes de Foo
.
Los miembros estáticos y las constantes se almacenan en el montón. A diferencia de los objetos en montón que pueden obtener la recolección de elementos no utilizados, los miembros estáticos y las constantes permanecen hasta que Appdomain se derribe. Por lo tanto, una vez se debe tener cuidado al tratar con campos estáticos.
Normalmente, las variables estáticas se almacenan en el segmento de datos de la memoria del programa. así que para cada clase que se crea / está en el programa en ejecución se creará la variable estática en el segmento de datos y todas las demás variables se inicializan en el segmento del código.
así que básicamente es como
+++++++++++++++++++++++++++++++++++++
+ DATA Segment
+ -static vars
+
+----------------------------------
+ instances | instances | instances|
+ | | |
aquí el área individual se comparte entre las instancias.
de wikipedia "El área de datos contiene variables globales y estáticas utilizadas por el programa que son
explícitamente inicializado con un valor ".
Para Java, los objetos a los que se refieren los campos estáticos residen en el montón como otros objetos:
El montón es el área de datos de tiempo de ejecución a partir de la cual se asigna la memoria para todas las instancias de clase y matrices.
El campo se inicializará (si la declaración contiene una inicialización) cuando se cargue la clase , lo que ocurre inmediatamente antes de la primera aparición de cualquiera de los siguientes:
- se crea una instancia de la clase.
- Se invoca un método estático declarado por la clase.
- se asigna un campo estático declarado por la clase.
- se usa un campo estático declarado por la clase y el campo no es una variable constante (§4.12.4).
El acceso al campo estático se realiza mediante 2 instrucciones especiales de JVM, getstatic y putstatic . Pero aparte de esa distinción, los campos estáticos son similares a los campos no estáticos.
Por especificación, las variables estáticas se almacenan en el conjunto constante . JVM almacena esta información en Permanent Generation.
Puede haber excepciones, pero para los tipos de referencia la new
-keyword usualmente crea un objeto en una estructura de datos interna llamada "heap". El montón está gestionado por CLR (Common Language Runtime). No importa si tiene un miembro estático o de instancia o una variable local.
La diferencia entre los miembros estáticos y los miembros de instancia (los que no tienen la palabra clave static
) es que los miembros estáticos solo existen una vez por tipo (clase, estructura) y los miembros de instancia existen una vez por instancia (por objeto).
Es solo la referencia que es estática o no; esta distinción no se aplica al objeto al que se hace referencia (a menos que el objeto sea un tipo de valor). Un miembro estático, un miembro de instancia y una variable local pueden todos hacer referencia al mismo objeto.
Si bien los detalles exactos del sistema de tipos dependen de la implementación, permítanme entrar en algunos detalles más que simplemente indicando que depende y que no debería preocuparse . Describiré cómo funciona aproximadamente en la implementación de Microsoft (.NET) de acuerdo con el libro CLR a través de C # de Jeffrey Richter y el artículo Vea cómo el CLR crea objetos en tiempo de ejecución de Hanu Kommalapati et al. (problema original de MSDN de mayo de 2005 ).
Digamos que tienes una clase:
class Foo
{
// Instance fields
string myBar = "Foobar";
int myNum;
// Static fields
static string bar = "Foobar";
static int num;
}
Foo myFoo = new Foo();
Type typeOfFoo = typeof(Foo);
¿Dónde viven los campos de instancia?
Siempre que diga un new Foo()
, el espacio se asigna e inicializa para la instancia del objeto y se llama al constructor. Esta instancia se muestra como una instancia de Foo en la imagen a continuación. Tal instancia contiene solo los campos de instancia de la clase (en este caso myBar
y myNum
), y para los objetos asignados en el montón dos campos adicionales utilizados por el tiempo de ejecución ( Sync block index
y Type handle
). El manejador de tipo es un puntero a un objeto Type
que describe el tipo de instancia, en este caso tipo de Foo .
Cuando vuelve a decir new Foo()
, se asigna un nuevo espacio que volverá a contener espacio para los campos de instancia del tipo. Como puede ver, los campos de instancia están asociados con instancias de objeto.
El tiempo de ejecución coloca cada campo de instancia en un desplazamiento fijo desde el inicio de los datos del objeto. Por ejemplo, myBar
podría vivir en el desplazamiento +4. La dirección del campo de instancia es simplemente la dirección del objeto más el desplazamiento del campo.
¿Dónde viven los campos estáticos?
Los campos estáticos en C # y Java no están asociados con ninguna instancia de objeto, sino con un tipo. Las clases, estructuras y enumeraciones son ejemplos de tipos. Solo una vez (por tipo) es un espacio asignado para mantener los valores de los campos estáticos. Tendría sentido asignar espacio para los campos estáticos en la estructura Type
que describe el tipo, ya que también hay solo un objeto Type
por tipo. Este es el enfoque adoptado por C # y Java.
El objeto Type
1 se crea cuando el tipo de tiempo de ejecución lo carga. Esta estructura contiene todo tipo de información necesaria para que el tiempo de ejecución pueda asignar nuevas instancias, llamar a métodos y realizar transmisiones, entre otras cosas. También contiene el espacio para los campos estáticos, en este caso bar
y num
.
El tiempo de ejecución ha puesto a cada campo estático en algún desplazamiento desde el inicio de los datos del tipo. Esto es diferente para cada tipo. Por ejemplo, la bar
puede vivir en el desplazamiento +64. La dirección del campo estático es la dirección del objeto Type
más el desplazamiento del campo. El tipo es estáticamente conocido.
1 ) En Microsoft .NET, varias estructuras diferentes describen un tipo, como las estructuras MethodTable y EEClass .
Solo estoy familiarizado con C #, y esta es mi comprensión de eso:
Luego se inicia el programa, carga todos los ensamblados relacionados en un AppDomain. Cuando se carga la asamblea, 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.