Tipo de valor de Unity/C#, tipo de referencia, pila, montón, recolección de basura GC (teoría)

Tabla de contenido

1. El concepto de tipo de valor y tipo de referencia

Tipo de valor (valor):

Tipo de referencia (feferencia):

¿Están los tipos de referencia en el montón y los tipos de valor en la pila?

2. ¿Cuál es la diferencia entre los tipos de valor y los tipos de referencia?

3. Entonces, ¿qué son el montón y la pila? 

la pila

montón

4. Recolector de basura (GC)


Descargo de responsabilidad: este contenido proviene de varios materiales y resúmenes personales.

1. El concepto de tipo de valor y tipo de referencia

Tipo de valor (valor):

int float bool  struct  enumeración (enum) etc.

Tipo de referencia (feferencia):

La matriz de clase es una referencia, incluso si el elemento es un tipo de valor (int[] es una referencia). El delegado (delegate) es una referencia. La interfaz (interfaz) es una referencia, pero se puede implementar con un valor. tipo, etc

¿Están los tipos de referencia en el montón y los tipos de valor en la pila?

  1. No hay nada de malo en referirse a instancias de tipos que siempre están en el montón, pero las variables y los parámetros de métodos declarados dentro de los métodos están en la pila. Y el valor de una variable de instancia siempre se almacena donde se almacena la instancia misma. Por ejemplo, si hay una variable int en una clase, aunque sea un tipo de valor, está en el montón.
  2. Una variable de tipo de referencia contiene dos ubicaciones de almacenamiento: la ubicación de almacenamiento directamente asociada con la variable y la ubicación de almacenamiento a la que hace referencia el valor almacenado en la variable.
  3. Para la ubicación de almacenamiento directamente asociada con la variable y la ubicación de almacenamiento asociada con la variable de tipo de valor, no hay diferencia en su ubicación de almacenamiento, es decir, la referencia misma será la misma que el tipo de valor. poco tiempo, se asignará en el grupo de almacenamiento temporal de la pila. .

2. ¿Cuál es la diferencia entre los tipos de valor y los tipos de referencia?

  1. Después de la asignación, la diferencia entre si los dos valores cambian sincrónicamente, se asigna el tipo de valor y son independientes. El tipo de referencia se convierte en uno después de la asignación, y cuando un lado cambia, el otro lado también cambia. 

3. Entonces, ¿qué son el montón y la pila? 

  • la pila

La pila es un espacio especial reservado en la memoria, que se utiliza especialmente para almacenar pequeños valores de datos de corta duración, estos valores serán liberados automáticamente una vez que excedan sus funciones, por eso se les llama pilas. Al igual que la pila en la estructura de datos, la pila de memoria también tiene push y pop.
Todas las variables locales declaradas (como int a;) se colocarán en la pila, y su carga y descarga se controlará cuando se llame a la función. Es decir, las variables se han definido en la pila antes de que se ejecute el programa. Estas llamadas a funciones se expanden y contraen a través de la llamada pila de llamadas. Cuando se completa el procesamiento de la pila de llamadas para la función actual, vuelve al punto de llamada anterior a la pila de llamadas y continúa ejecutando el contenido restante desde la posición que dejó. antes. La ubicación de las asignaciones de memoria anteriores siempre se conoce y no es necesario realizar operaciones de limpieza de memoria porque las nuevas asignaciones de memoria sobrescriben los datos antiguos, por lo que la pila es relativamente eficiente.
El tamaño total de la pila suele ser pequeño, del orden de megabytes (MB). Al asignar más espacio del que puede soportar la pila, puede causar un desbordamiento de la pila, que ocurre cuando se ejecuta una gran cantidad de pilas de llamadas (como bucles infinitos) o cuando hay una gran cantidad de variables locales, pero la mayoría de las veces, a pesar del tamaño relativamente pequeño de la pila, pero rara vez causa el desbordamiento de la pila.

  • montón

El montón representa el resto del espacio de memoria y se utiliza para la mayoría de las asignaciones de memoria**. Dado que queremos que la mayoría de las asignaciones de memoria se mantengan durante más tiempo que la llamada de función actual, no se pueden asignar en la pila, porque la pila sobrescribirá los resultados generados antes y después de que finalice la ejecución del método. Debido a que los tipos de datos a veces son demasiado grandes o deben mantenerse fuera de la función, hay un montón. Físicamente no hay diferencia entre el montón y la pila, ambos son solo espacios de memoria que contienen bytes de datos que existen en la RAM. El sistema operativo solicita y guarda estos bytes de datos. La diferencia es cuándo, dónde y cómo se utilizan.
En el código nativo, como los lenguajes escritos en C++, estas asignaciones de memoria se manejan manualmente y es nuestra responsabilidad garantizar que todos los bloques de memoria se asignen correctamente y liberar memoria explícitamente cuando no se necesite. De lo contrario, es fácil causar fugas de memoria hasta que la memoria es insuficiente y el programa falla.
En los lenguajes administrados, el recolector de basura maneja automáticamente la liberación de memoria. Durante la inicialización del programa Unity, la plataforma Mono solicita una cadena de memoria del sistema operativo para generar un espacio de memoria en montón (generalmente llamado montón administrado) para su uso. por código C#. Este espacio de almacenamiento dinámico comienza siendo relativamente pequeño, menos de 1 MB, pero crece a medida que el código de script requiere nuevos fragmentos de memoria. Si Unity ya no lo necesita, ese espacio puede reducirse al liberarlo de nuevo en el sistema operativo.

4. Recolector de basura (GC)

Garbage Collector (GC) tiene la importante función de garantizar que no se use más memoria administrada de la necesaria y que la memoria que ya no se necesita se recupere automáticamente. En otras palabras, GC participará en la creación y destrucción de objetos. Por ejemplo: si crea un GameObject y luego lo destruye, el GC marcará el espacio de memoria utilizado por el objeto para que esta memoria pueda recuperarse más adelante. Tenga en cuenta que la recuperación de la memoria no es en tiempo real, pero la memoria solo se recupera cuando no se necesita.

El GC en la versión de Mono que usa Unity es un GC de rastreo que usa una estrategia de marcar y barrer. El algoritmo se divide en dos fases:

Cada objeto asignado es rastreado por un bit adicional de datos. Este bit de datos indica si el objeto está marcado. Estas banderas se establecen en falso, lo que indica que no se ha marcado. Cuando comienza el proceso de recopilación, marca todos los objetos que aún son accesibles para el programa al establecer el indicador Alive del objeto en verdadero. Los objetos accesibles son referencias directas (como variables estáticas o locales en la pila) o referencias indirectas a través de campos (variables miembro) de otros objetos accesibles directa o indirectamente. En teoría, todos los objetos sin referencia deberían reciclarse.
La segunda fase consiste en iterar sobre dichas referencias (que el GC rastreará a lo largo de la vida del programa) y decidir, en función de su estado de marcado, si se debe reclamar. Si un objeto no está marcado, se considera candidato para la colección. Esta fase omite los objetos que ya se han marcado, pero los restablece en falso antes del próximo análisis de recolección de elementos no utilizados para completar una nueva ronda de marcado.
Cuando finalice la ejecución de la segunda fase, todos los objetos no marcados se recuperarán formalmente para liberar espacio y luego se revisará la solicitud de accidente para crear objetos. Si el GC ha liberado suficiente espacio, asigne memoria en el espacio recién liberado y regrese al llamador. Si el espacio liberado no es suficiente, solo puede solicitar más montones administrados del sistema.

De hecho, el GC mantiene una lista de todos los objetos en la memoria, mientras que la aplicación mantiene otra lista separada que contiene solo algunos de ellos. Tan pronto como el programa termina con el objeto, simplemente olvida que existe y lo elimina de la lista, sin importar si el objeto necesita ser reciclado o no. En otras palabras, el GC realiza de forma independiente el trabajo de recolección de elementos no utilizados y el programa solo necesita mantener su propia lista de objetos.

Los juegos tienen requisitos de alto rendimiento. Para mejorar la eficiencia, se puede llamar a GC cuando se cambian las escenas o los recursos no se usan con frecuencia.

Supongo que te gusta

Origin blog.csdn.net/q1295006114/article/details/130915670
Recomendado
Clasificación