En su ejemplo, myApple
tiene el valor especial null
(generalmente todos los bits cero), por lo que no hace referencia a nada. El objeto al que se refería originalmente ahora se pierde en el montón. No hay forma de recuperar su ubicación. Esto se conoce como pérdida de memoria en sistemas sin recolección de basura.
Si originalmente configuró 1000 referencias en nulo, entonces tiene espacio para solo 1000 referencias, generalmente 1000 * 4 bytes (en un sistema de 32 bits, el doble que en 64). Si esas 1000 referencias apuntaban originalmente a objetos reales, entonces asignó 1000 veces el tamaño de cada objeto, más espacio para las 1000 referencias.
En algunos lenguajes (como C y C ++), los punteros siempre apuntan a algo, incluso cuando están "sin inicializar". El problema es si la dirección que tienen es legal para que su programa acceda. La dirección especial cero (aka null
) no se asigna deliberadamente a su espacio de direcciones, por lo que la unidad de administración de memoria (MMU) genera un error de segmentación cuando se accede a él y su programa se bloquea. Pero dado que la dirección cero deliberadamente no está asignada, se convierte en un valor ideal para usar para indicar que un puntero no apunta a nada, de ahí su papel como null
. Para completar la historia, al asignar memoria con new
omalloc()
, el sistema operativo configura la MMU para asignar páginas de RAM en su espacio de direcciones y se vuelven utilizables. Por lo general, todavía hay vastos rangos de espacio de direcciones que no están asignados y, por lo tanto, también provocan fallas de segmentación.
std::shared_ptr<Apple>
es un ejemplo que no es ni GC ni pierdeApple
cuando se pone a cero.shared_ptr
solo una forma básica de recolección de basura? GC no requiere que haya un "recolector de basura" separado, solo que se produce la recolección de basura.La respuesta depende del idioma que estés usando.
C / C ++
En C y C ++, la palabra clave era NULL, y lo que realmente era NULL era 0. Se decidió que "0x0000" nunca sería un puntero válido a un objeto, y ese es el valor que se asigna para indicar que No es un puntero válido. Sin embargo, es completamente arbitrario. Si intentas acceder a él como un puntero, se comportaría exactamente como un puntero a un objeto que ya no existe en la memoria, provocando una excepción de puntero no válida. El puntero mismo ocupa memoria, pero no más de lo que lo haría un objeto entero. Por lo tanto, si tiene 1000 punteros nulos, es el equivalente a 1000 enteros. Si algunos de esos punteros apuntan a objetos válidos, entonces el uso de la memoria sería el equivalente a 1000 enteros más la memoria contenida en esos punteros válidos. Recuerda que en C o C ++,no implica que se haya liberado memoria, por lo que debe eliminar explícitamente ese objeto utilizando dealloc (C) o eliminar (C ++).
Java
A diferencia de C y C ++, en Java nulo es simplemente una palabra clave. En lugar de administrar nulo como un puntero a un objeto, se administra internamente y se trata como un literal. Esto eliminó la necesidad de vincular los punteros como tipos enteros y permite que Java abstraiga los punteros por completo. Sin embargo, incluso si Java lo oculta mejor, siguen siendo punteros, lo que significa que 1000 punteros nulos aún consumen el equivalente de 1000 enteros. Obviamente, cuando apuntan a objetos, al igual que C y C ++, la memoria es consumida por esos objetos hasta que no haya más punteros que los hagan referencia, sin embargo, a diferencia de C y C ++, el recolector de basura lo recoge en su próxima pasada y libera la memoria, sin requerir que tenga que hacer un seguimiento de qué objetos se liberan y cuáles no, en la mayoría de los casos (a menos que tenga razones para hacer referencia débil a los objetos, por ejemplo).
fuente
NULL
( por cierto, no una palabra clave) se tratan como si fueran cero bits. Pero no necesitan implementarse como tales, y de hecho algunas implementaciones oscuras sí usan punteros nulos distintos de cero. Si escriboif (myptr == 0)
, el compilador hará lo correcto, incluso si el puntero nulo está representado internamente por0xabcdef
.0
es una constante de puntero nulo, pero esto no significa quemyptr == 0
compruebe si todos los bits demyptr
son cero.NULL
macro en absoluto, sino por hablar sobre el "puntero nulo" y mencionar explícitamente que "literal-0 se puede convertir implícitamente en un puntero nulo".Un puntero es simplemente una variable que es principalmente de tipo entero. Especifica una dirección de memoria donde se almacena el objeto real.
La mayoría de los idiomas permiten acceder a los miembros del objeto a través de esta variable de puntero:
El compilador sabe cómo acceder a los miembros de un
Apple
. "Sigue" el puntero amyApple
la dirección y recupera el valor deappleInt
Si asigna el puntero nulo a una variable de puntero, hace que el puntero apunte a ninguna dirección de memoria. (Lo que hace imposible el acceso de los miembros).
Para cada puntero necesita memoria para mantener el valor entero de la dirección de memoria (principalmente 4 bytes en sistemas de 32 bits, 8 bytes en sistemas de 64 bits). Esto también es cierto para los punteros nulos.
fuente
Ejemplo rápido (tenga en cuenta que los nombres de variables no se almacenan):
Aclamaciones.
fuente