===== Diretório de artigos =====
Referências fortes, referências suaves, referências fracas e referências fantasmas
Citação forte
new
Objetos 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 OutOfMemoryError
objeto 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.SoftReference
para 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 options
preencha os seguintes parâmetros
-Xms5m -Xmx5m -XX:+PrintGCDetails
Finalmente, clique com o botão direito para executar.
Diagrama de configuração
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
Referência fraca
Necessário Object.Reference.WeakReference
para 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
HashMap
Mesmo key==null
que 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 Spring
uma 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 poll
podem 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)