Conhecimento básico de Java Referência forte de JVM, referência suave, referência fraca e referência falsa (incluindo perguntas da entrevista)

Referências fortes, referências suaves, referências fracas e referências fantasmas

Citação forte

newObjetos criados usando métodos são referências fortes por padrão. Durante o GC, mesmo que a memória não seja suficiente , o OutOfMemoryErrorobjeto não será recuperado se for lançado e não será recuperado se morrer . Consulte StrongReferenceDemo para obter detalhes .

public class StrongReferenceDemo {
    public static void main(String[] args) {
        Object o1=new Object();
        Object o2=new Object();
        o1=null;
        System.gc();
        System.out.println(o2);
    }
}

Referência suave

Necessário Object.Reference.SoftReferencepara criar o display. Se houver memória suficiente , ela não será recuperada durante o GC . Se a memória não for suficiente , ela será reciclada . Freqüentemente usado em aplicativos sensíveis à memória, como caches. Consulte SoftReferenceDemo para obter detalhes .
A folha de configuração da JVM, deliberadamente gera grandes objetos e configura pequena memória, de forma que sua memória não seja suficiente para causar OOM, dependendo da recuperação de referências soft

Condição 1. Crie um objeto grande

 byte[] bytes = new byte[30 * 1024 * 1024];//一个30M的对象

Condição 2. Como configurar uma pequena memória

Em IDEA菜单栏---Run---Edit Configurations ---VM optionspreencha os seguintes parâmetros

 -Xms5m -Xmx5m -XX:+PrintGCDetails

Finalmente, clique com o botão direito para executar.

Diagrama de configuração
Insira a descrição da imagem aqui

Código

import java.lang.ref.SoftReference;

public class SoftReferenceDemo {
    public static void main(String[] args) {
        System.out.println("软引用内存充足的情况");
        softRef_Memory_Enough();
        System.out.println();
        System.out.println("软引用内存不足的情况");
        softRef_Memory_NotEnough();
    }

    /**
     * 内存够用的时候就保留,不够用就回收!
     */
    private static void softRef_Memory_Enough() {
        Object o1 = new Object();
        SoftReference<Object> softReference = new SoftReference<>(o1);
        System.out.println(o1);
        System.out.println(softReference.get());
        System.out.println("===========");
        o1 = null;
        System.gc();
        System.out.println(o1);
        System.out.println(softReference.get());
    }

    /**
     * JVM配置单,故意产生大对象并配置小的内存,让它内存不够用导致OOM,看软引用的回收情况
     * IDEA菜单栏---Run---Edit Configurations ---VM options---填写以下参数
     * -Xms5m -Xmx5m -XX:+PrintGCDetails
     * 右键run
     */
    private static void softRef_Memory_NotEnough() {
        Object o1 = new Object();
        SoftReference<Object> softReference = new SoftReference<>(o1);
        System.out.println(o1);
        System.out.println(softReference.get());
        System.out.println("===========");
        o1 = null;
        //System.gc();

        try {
            byte[] bytes = new byte[30 * 1024 * 1024];//一个30M的对象
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println(o1);
            System.out.println(softReference.get());
        }
    }
}

Resultado
Insira a descrição da imagem aqui

Referência fraca

Necessário Object.Reference.WeakReferencepara criar o display. Independentemente de a memória ser suficiente ou não, ela é recuperada durante o GC e também pode ser usada para cache. Veja WeakReferenceDemo para detalhes

Código

import java.lang.ref.WeakReference;

public class WeakReferenceDemo {
    public static void main(String[] args) {
        Object o1 = new Object();
        WeakReference<Object> weakReference = new WeakReference<>(o1);
        System.out.println(o1);
        System.out.println(weakReference.get());
        System.out.println("==========");
        o1 = null;
        System.gc();
        System.out.println(o1);
        System.out.println(weakReference.get());
    }
}

WeakHashMap

HashMapMesmo key==nullque seja tradicional , os pares de valores-chave não serão reciclados. Mas se for WeakHashMap, uma vez que a memória é insuficiente key==null, o par de valores-chave será reciclado. Consulte WeakHashMapDemo para obter detalhes .

package jvm;

import java.util.HashMap;
import java.util.WeakHashMap;

public class WeakHashMapDemo {
    
    
    public static void main(String[] args) {
    
    
        myHashMap();
        System.out.println("===============");
        myWeakHashMap();
    }

    private static void myHashMap() {
    
    
        HashMap<Integer, String> map = new HashMap<>();
        Integer key = 1;
        String value = "HashMap";
        map.put(key, value);
        System.out.println(map);

        key = null;
        System.out.println(map);
        System.gc();
        System.out.println(map + "\t" + map.size());
    }

    private static void myWeakHashMap() {
    
    
        WeakHashMap<Integer, String> map = new WeakHashMap<>();
//        Integer key = 2;
        Integer key = new Integer(2);
        String value = "WeakHashMap";
        map.put(key, value);
        System.out.println(map);

        key = null;
        System.out.println(map);

        System.gc();
        System.out.println(map + "\t" + map.size());
    }
}

Resultado

{
    
    1=HashMap}
{
    
    1=HashMap}
{
    
    1=HashMap}	1
===============
{
    
    2=WeakHashMap}
{
    
    2=WeakHashMap}
{
    
    }	0

Referência fantasma

Aplicativos soft e referências fracas podem get()obter objetos por meio de métodos, mas referências fantasmas não. Citações fictícias nada mais são do que GC a qualquer momento e não podem ser usadas sozinhas. Elas devem ser usadas em conjunto com ReferenceQueue . O único propósito de definir uma referência fictícia é receber uma notificação para operações subsequentes quando o objeto é reciclado , um pouco como Springuma pós-notificação. Consulte PhantomReferenceDemo para obter detalhes .

Fila de referência

Depois que as referências fracas e referências fantasmas forem recicladas, elas serão colocadas na fila de referência e pollpodem ser obtidas por meio de métodos. Para o uso de filas de referência e referências fracas e virtuais, consulte ReferenceQueueDemo .

Código

package jvm;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

public class PhantomReferenceDemo {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        Object o1 = new Object();
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        PhantomReference phantomReference = new PhantomReference(o1, referenceQueue);
        System.out.println(o1);
        System.out.println(phantomReference.get());
        System.out.println(referenceQueue.poll());

        System.out.println("===========");

        o1 = null;
        System.gc();
        Thread.sleep(500);
        System.out.println(o1);
        System.out.println(phantomReference.get());
        System.out.println(referenceQueue.poll());
    }
}

Resultado

java.lang.Object@1b6d3586
null
null
===========
null
null
java.lang.ref.PhantomReference@4554617c

Cenários aplicáveis ​​de referências suaves e fracas

Se houver um aplicativo que precise ler muitas fotos locais

  • Se a imagem for lida do disco rígido toda vez que for lida, o desempenho será seriamente afetado.
  • Se for carregado na memória de uma vez, pode causar estouro de memória.

Neste momento, o uso de referências virtuais pode resolver este problema. A
ideia do projeto é usar um HashMap para salvar a relação de mapeamento entre o caminho da imagem e a referência virtual associada ao objeto de imagem correspondente. Quando a memória for insuficiente, a
JVM irá recuperar automaticamente os objetos de imagem em cache ocupados. Espaço, evitando assim efetivamente problemas de OOM

Map<String, SoftReference<Bitmap>> image Cache= new Hash Map<String, SoftReference<Bitmap>>0)

Resumindo

Insira a descrição da imagem aqui

de outros

A diferença entre = e nova criação em Inteiro

Acho que você gosta

Origin blog.csdn.net/e891377/article/details/108763147
Recomendado
Clasificación