Cuatro referencias a objetos java: fuerte, suave, débil y virtual

Introducción

El mecanismo de recolección de basura de Java utiliza dos métodos para determinar si un objeto se reclama, a saber, el método de recuento de referencias y el algoritmo de análisis de accesibilidad.

Antes de jdk1.2, solo hay un tipo de referencia. Cuando se hace referencia al objeto, existirá. Cuando no hay referencia, el recuento de referencias es 0 y el objeto será juzgado como no válido por la recolección de basura.

Java comenzó con jdk1.2. Hay cuatro tipos de referencias a objetos, a saber, referencias fuertes > referencias suaves> referencias débiles> referencias virtuales . Los programadores pueden controlar el ciclo de vida de los objetos a través de diferentes referencias para facilitar la recolección de basura y hacer que el programa sea más flexible. Ciclo de vida del objeto de control

Inserte la descripción de la imagen aquí
Java se inició en jdk1.2 y proporcionó una referencia de clase abstracta y tres clases de implementación SoftReference ( referencia suave ), WeakReference ( referencia débil ), PhantomReference ( referencia virtual ) en java.lang.ref

Fuerte referencia

/**
     * 强引用
     */
    public void testStrongReference(){
    
    
        //强引用
        Object obj=new Object();
    }

La mayoría de los objetos en el código comercial son referencias fuertes, como Object obj = new Object (). Dichos objetos referenciados nunca serán recolectados como basura . Cuando la memoria no es suficiente para asignar la memoria para crear el objeto, la máquina virtual Java arrojará Un error OOM hace que el programa finalice de manera anormal y este objeto no se recicla. Solo después de que la referencia desaparece (* Asignada explícitamente a nulo *, finaliza el ciclo de vida del método, etc.), el recuento de referencias será 0 antes de que se recolecte la basura.

Referencia suave

/**
     * 软引用
     */
    public void testSoftReference(){
    
    
        //强引用
        Object obj=new Object();
        //放入SoftReference
        SoftReference<Object> softReference = new SoftReference<Object>(obj);
        System.out.println( softReference.get());//java.lang.Object@39a054a5
    }

Las referencias suaves son un nivel más bajo que las referencias fuertes. Se utilizan para representar objetos útiles y no esenciales . Solo cuando la memoria es insuficiente, los objetos de referencia suave serán recolectados basura , que se puede usar para lograr el almacenamiento en caché sin preocuparse por el desbordamiento de la memoria.

/**
     * 软引用(引用队列)
     */
    public void testSoftReferenceQueue(){
    
    
        //引用队列
        ReferenceQueue referenceQueue = new ReferenceQueue<>();

        //使用守护线程
        Thread thread= new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    int i=0;
                    SoftReference<Integer> softReference;
                    //如果对象被gc回收
                    while((softReference = (SoftReference) referenceQueue.remove()) != null) {
    
    
                        System.out.println("第"+i+"次回收:"+softReference);
                        i++;
                    }
                }catch (Exception e){
    
    

                }
            }
        });
        thread.setDaemon(true);//设置为守护线程,监听对象变化
        thread.start();

        Map<Object, Object> map = new HashMap<>();
        Object obj=new Object();
        for(int i=0;i<2000; i++){
    
    
            //放入SoftReference转为软引用
            byte [] bytes=new byte[1024*1024];
            SoftReference<byte []> softReference = new SoftReference<byte []>(bytes,referenceQueue);
            //将软引用作为key
            map.put(softReference,obj);
        }
    }

第 1992 次 回收 : java.lang.ref.SoftReference@7c7a06ec
第 1993 次 回收 : java.lang.ref.SoftReference@1d296da
第 1994 次 回收 : java.lang.ref.SoftReference@776aec5c
[GC (Allocation Failure) [PSYoungGen : 30K-> 64K (1536K)] 3833K-> 3866K (5632K), 0.0002270 segundos] [Tiempos: usuario = 0.00 sys = 0.00, real = 0.00 segundos]
[GC (falla de asignación) [PSYoungGen: 64K-> 64K (1536K )] 3866 K-> 3866 K (5632 K), 0,0002042 segundos] [Veces: usuario = 0.00 sys = 0.00, real = 0.00 segundos]
[GC completo (falla de asignación) [PSYoungGen: 64K-> 0K (1536K)] [ParOldGen: 3802K -> 3802K (4096K)] 3866K-> 3802K (5632K), [Metaspace: 3120K-> 3120K (1056768K)], 0.0019695 segundos] [Tiempos: usuario = 0.00 sys = 0.00, real = 0.00 segundos]
[GC (Fallo de asignación ) [PSYoungGen: 0K-> 0K (1536K)] 3802K-> 3802K (5632K), 0.0002220 segundos] [Tiempos: usuario = 0.00 sys = 0.00, real = 0.00 segundos]
[GC completo (falla de asignación) [PSYoungGen: 0K-> 0K (1536K)] [ParOldGen: 3802K-> 730K (4096K)] 3802K-> 730K (5632K), [Metaspace: 3120K-> 3120K (1056768K)], 0.0025588 segundos] [Tiempos: usuario = 0.00 sys = 0.00, real = 0.00 segundos]
La recuperación de 1995: java.lang.ref.SoftReference@408d971b
La recuperación de 1996: java.lang.ref.SoftReference@75d4a5c2
La recuperación de 1997: java.lang.ref.SoftReference@557caf28

La referencia suave es implementada por SoftReference. El objeto de referencia suave se puede registrar en la cola de referencia (Referencequeue), y la cola de referencia se usa para determinar si el objeto está liberado. La referencia tiene un campo siguiente. Hay cuatro estados que se pueden juzgar según el estado, pero el siguiente solo está en Ponerlo en la cola tendrá sentido (porque, solo cuando se pone en cola, next se establecerá en el siguiente objeto de referencia que se procesará)
Inserte la descripción de la imagen aquí
activo: el estado en el que se asigna la memoria.
pendiente: el estado en el que la memoria está a punto de ser reclamada y almacenada en la cola de referencia asociada.
Enqueued: cuando se recupera la memoria, entra en el estado de la cola de referencia.
Inactivo: estado inactivo.

Referencia débil

/**
     * 弱引用
     */
    public void testWeakReference(){
    
    
        //强引用
        Object obj=new Object();
        //放入WeakReference
        WeakReference<Object> weakReference = new WeakReference<Object>(obj);
        System.out.println(weakReference.get());//java.lang.Object@39a054a5
    }

Las referencias débiles son el primer nivel que las referencias suaves. Se utilizan para representar objetos no esenciales . Independientemente de si la memoria es suficiente, sus objetos se recolectarán como basura. Sin embargo, debido a que la prioridad del hilo de recolección de basura es muy baja,
las referencias débiles no se recopilarán rápidamente a través de WeakReference. Para la implementación, el objeto de referencia débil se puede registrar en la cola de referencia (Referencequeue) y la cola de referencia se utiliza para determinar si el objeto se libera. Si desea probar, puede usar el método de monitoreo de subprocesos al que se hace referencia débilmente anteriormente

Referencia fantasma

/**
     * 虚引用
     */
    public void testPhantomReference(){
    
    
        //强引用
        Object obj=new Object();
        //必须使用引用队列
        ReferenceQueue referenceQueue = new ReferenceQueue();
        //放入PhantomReference
        PhantomReference<Object> phantomReference = new PhantomReference<Object>(obj,referenceQueue);
        System.out.println(phantomReference.get());//null 因为虚引用无法获取对象实例,只是监听作用
        System.out.println(obj);//java.lang.Object@39a054a5
    }

Referencias virtuales
En comparación con otras referencias, las referencias virtuales son como referencias virtuales. Las instancias de objeto no se pueden obtener a través de referencias virtuales. Si un objeto solo está retenido por referencias virtuales, se recolectará como basura en cualquier momento . A diferencia de las referencias suaves y las referencias débiles, debe Registrado en Referencequeue , cuando el objeto está a punto de ser reciclado, colocará la referencia virtual en la cola de referencia y juzgará si el objeto debe reciclarse juzgando si la referencia virtual se agrega a la cola de referencia.

Supongo que te gusta

Origin blog.csdn.net/qq_38306425/article/details/106685465
Recomendado
Clasificación