Si un objeto en la memoria no tiene referencia, significa que el objeto ya no se usa, y puede convertirse en un candidato para la recolección de basura. Sin embargo, debido a que el tiempo de ejecución del recolector de basura es incierto, el tiempo de reciclaje real de los objetos que se pueden recolectar basura es incierto. Para un objeto, siempre que haya una referencia, siempre existirá en la memoria. Si hay más y más objetos como este, superando la memoria total en el JVM, el JVM arrojará un error de Memory. Aunque la operación específica de la recolección de basura es controlada por el JVM, los desarrolladores aún pueden interactuar con el recolector de basura hasta cierto punto, y el propósito es ayudar mejor al recolector de basura a administrar la memoria de la aplicación. Este método de interacción es usar el paquete Java.lang.Ref introducido por JDK 1.2.
1 cita fuerte
Las citas fuertes son las citas más comunes utilizadas. Si un objeto tiene una referencia fuerte, el recolector de basura nunca lo reciclará. Cuando el espacio de memoria es insuficiente, la máquina virtual Java preferiría lanzar un error de MemoryError para hacer que el programa termine anormalmente y no reciclaría objetos con fuertes referencias para resolver el problema de la memoria insuficiente.
Por ejemplo, fecha fecha = nueva fecha (), la fecha es una sólida referencia a un objeto. Se pueden aprobar fuertes referencias a objetos en todas partes del programa. En muchos casos, múltiples referencias apuntarán al mismo objeto al mismo tiempo. La existencia de fuertes referencias limita el tiempo de supervivencia de un objeto en la memoria. Si el objeto A contiene una fuerte referencia al objeto B, entonces, en general, el tiempo de supervivencia del objeto B no será más corto que el objeto A. Si el objeto A no establece explícitamente la referencia del objeto B a NULL, solo después de que el objeto A es la basura recolectado Banci ya no tendrá una referencia apuntando a él, y será posible que la oportunidad sea para que se recopile la base.
Código de ejemplo:
paquete com.skywang.java; public class StrongReferenceTest {public static void main (string [] args) {mydate date = new myDate (); System.gc (); }} Resultados de ejecución:
<No salida>
El resultado muestra que a pesar de que la recolección de basura se llama explícitamente, es una referencia sólida para la fecha, y la fecha no se recicla.
Además de fuertes referencias, el paquete java.lang.ref proporciona diferentes métodos de referencia a un objeto. El recolector de basura del JVM tiene diferentes formas de manejar diferentes tipos de referencias.
2 citas suaves
Si un objeto solo tiene referencias suaves, el espacio de memoria es suficiente y el recolector de basura no lo reciclará; Si el espacio de memoria es insuficiente, la memoria de estos objetos se reciclará. Mientras el recolector de basura no lo recicle, el programa puede usar el objeto. Las referencias suaves se pueden usar para implementar cachés sensibles a la memoria.
Se puede usar una referencia suave junto con una cola de referencia (referencequeue). Si el objeto mencionado por la referencia suave es reciclado por el recolector de basura, la máquina virtual Java agregará la referencia suave a la cola de referencia asociada.
Las referencias suaves son más débiles que las referencias fuertes en la fuerza y están representadas por Softreference. Su función es decirle al recolector de basura qué objetos en el programa son menos importantes y pueden reciclarse temporalmente cuando no hay memoria insuficiente. Cuando no hay suficiente memoria en el JVM, el recolector de basura libera objetos que solo apuntan por referencias suaves. Si se liberan todos estos objetos y la memoria es insuficiente, se lanzará un error OutOfMemory. Las referencias suaves son ideales para crear cachés. Cuando el sistema es insuficiente, se puede liberar el contenido en el caché. Por ejemplo, considere un programa de editor de imágenes. El programa leerá todo el contenido del archivo de imagen en la memoria para un fácil procesamiento. Los usuarios también pueden abrir múltiples archivos al mismo tiempo. Cuando hay demasiados archivos abiertos al mismo tiempo, puede causar memoria insuficiente. Si se utilizan referencias suaves para señalar el contenido del archivo de imagen, el recolector de basura puede recuperar esta memoria cuando sea necesario.
Código de ejemplo:
paquete com.skywang.java; import java.lang.ref.softreference; public class SoftreferenceTest {public static void main (string [] args) {Softreference ref = new Softreference (new myDate ()); ReferenceTest.DrainMemory (); }} Resultados de ejecución:
<No salida>
Resultados: Cuando la memoria es insuficiente, la referencia suave se termina. Cuando se prohíben las referencias suaves,
Softreference ref = new Softreference (new MyDate ()); referenceTest.DrainMemory ();
Equivalente a
MyDate date = new myDate (); // depende de la jvm ejecutar si (jvm.infient Memory ()) {date = null; System.gc ();} 3 citas débiles
La referencia débil es más débil que la referencia blanda en la fuerza y se expresa por la clase de referencia débil. Su propósito es referirse a un objeto, pero no evita que el objeto se recicle. Si se usa una referencia fuerte, siempre que exista la referencia, el objeto referenciado no se puede reciclar. Las citas débiles no tienen este problema. Cuando el recolector de basura se está ejecutando, si todas las referencias a un objeto son referencias débiles, el objeto se reciclará. La función de las referencias débiles es resolver la relación de acoplamiento entre los objetos en el tiempo de supervivencia traídos por fuertes referencias. El uso más común de referencias débiles es en las clases de recolección, especialmente en las tablas hash. La interfaz de tabla hash permite que cualquier objeto Java se use como clave. Cuando se coloca un par de valor clave en la tabla hash, el objeto de tabla hash tiene una referencia a estos objetos clave y valor. Si esta referencia es una referencia sólida, entonces mientras el objeto de tabla hash todavía esté vivo, los objetos de clave y valor contenidos en ella no se reciclarán. Si una tabla hash con un largo tiempo de supervivencia contiene muchos pares de valor clave, eventualmente puede consumir toda la memoria en el JVM.
La solución a esta situación es usar referencias débiles para hacer referencia a estos objetos para que los objetos de clave y valor en la tabla hash puedan ser recolectados de basura. Deakhashmap se proporciona en Java para satisfacer esta necesidad común.
Código de muestra:
paquete com.skywang.java; import java.lang.ref.weakReference; public class débeReferenceTest {public static void main (string [] args) {weakReference ref = new WeakReference (new MyDate ()); System.gc (); }} Resultados de ejecución:
OBJ [Fecha: 1372142034360] es GC
Resultados: Cuando se ejecuta la recolección de basura JVM, se terminan las referencias débiles.
Débil reference ref = new WeakReference (new MyDate ()); System.gc ();
Equivalente a:
MyDate date = new myDate (); // recolección de basura if (jvm.infient memoria ()) {date = null; System.gc ();} La diferencia entre referencias débiles y referencias suaves es que los objetos con solo referencias débiles tienen un ciclo de vida más corto. Durante el proceso de un hilo de recolector de basura escaneando el área de memoria bajo su jurisdicción, una vez que se encuentra un objeto con solo referencias débiles, su memoria se reciclará independientemente de si el espacio de memoria actual es suficiente o no. Sin embargo, dado que el recolector de basura es un hilo con muy baja prioridad, no necesariamente se descubre muy rápidamente para objetos que solo tienen referencias débiles.
Se puede usar una referencia débil junto con una cola de referencia (referencequeue). Si el objeto mencionado por una referencia débil es la basura recolectada, la máquina virtual Java agregará la referencia débil a la cola de referencia asociada.
4 citas de ilusión
También conocido como Cotizaciones de Ghost ~ Antes de introducir citas de fantasmas, primero debemos introducir el mecanismo de terminación de objetos proporcionado por Java. Hay un método finalizar en la clase de objeto. La intención original de su diseño es realizar algunos trabajos de limpieza antes de que un objeto sea realmente reciclado. Debido a que Java no proporciona un mecanismo similar al destructor de C ++, se implementa a través del método finalizado. Pero el problema es que el tiempo de ejecución del recolector de basura no se fija, por lo que no se puede predecir el tiempo de ejecución real de estos trabajos de limpieza. Una referencia fantasma puede resolver este problema. Al crear una fantomreferencia de referencia fantasma, debe especificar una cola de referencia. Cuando se ha llamado al método final de un objeto, la referencia fantasma del objeto se agregará a la cola. Al verificar los contenidos en la cola, sabrá si un objeto está listo para ser reciclado.
El uso de referencias fantasmas y sus colas es raro, y se usa principalmente para implementar un control de uso de memoria relativamente fino, que es muy significativo para los dispositivos móviles. El programa puede solicitar la memoria para crear un nuevo objeto después de determinar que un objeto se reciclará. De esta manera, la memoria consumida por el programa puede mantenerse en una cantidad relativamente baja.
Por ejemplo, el siguiente código da un ejemplo de la implementación de un búfer.
clase pública Phantombuffer {private byte [] data = new byte [0]; REFERENCIA PRIVADOQUEUE <byte []> queue = new RefectionQueue <byte []> (); Phantomreference privado <byte []> ref = new Phantomreference <byte []> (datos, cola); public byte [] get (int size) {if (size <= 0) {tire nueva ilegalargumentException ("tamaño de búfer incorrecto"); } if (data.length <size) {data = null; System.gc (); // Fuerza ejecuta el recolector de basura try {queue.remove (); // Este método se bloqueará hasta que la cola sea no vacía ref.clear (); // La referencia de Ghost no se borrará automáticamente, debe ejecutar ref = null; data = nuevo byte [tamaño]; ref = new Phantomreference <byte []> (datos, cola); } catch (InterruptedException e) {E.PrintStackTrace (); }} Datos de retorno; }} En el código anterior, cada vez que se aplica un nuevo búfer, primero se asegura que la matriz de bytes del búfer anterior se haya reciclado con éxito. El método de eliminación que hace referencia a la cola bloqueará hasta que se agregue una nueva referencia fantasma a la cola. Sin embargo, debe tenerse en cuenta que este enfoque hará que el recolector de basura se ejecute demasiadas veces, lo que puede hacer que el programa sea demasiado bajo rendimiento.
Código de muestra:
paquete com.skywang.java; import java.lang.ref.referenceue; import java.lang.ref.phantomreference; public class PhantomReferenceNest {public static void main (string [] args) {referenceue Queue = nueva referencia de referencia (); Phantomreference ref = new Phantomreference (new MyDate (), cola); System.gc (); }} Resultados de ejecución:
OBJ [Fecha: 1372142282558] es GC
El resultado muestra que la referencia de ilusión se termina después de la instancia.
ReferenceQueue queue = new RefectionQueue (); Phantomreference ref = new Phantomreference (new MyDate (), queue); System.gc ();
Equivalente a:
MyDate date = new myDate (); date = null;