强引用 、软引用、 弱引用、虚引用分别是什么

强引用:基本是用到的95%都是强引用

当内存不足 jvm开始垃圾回收 对于强引用的对象 就算是出现oom也不会对该对象进行回收 死也不收

在java中最常见的就是强引用 把一个对象赋给一个引用变量 这个引用变量就是强引用 当一个对象被强引用变量引用的时 他处于不可达状态 他是不可能被垃圾回收的 这也是强引用造成内存泄漏的主要原因之一

对于一个普通的对象 如果没有其他的引用关系 只要超过引用的作用域或者将相应的强引用赋值为null一般认为就是可以被回收的。

/**
    只会收集obj1
*/
Object obj1=new Object();//默认强引用
Object obj2=obj1;//引用赋值
obj1=null;//置空
Syetem.gc();//垃圾回收

软引用:当内存充足时不会回收 内存不足时回收

/**
内存充足时 软引用不会回收
*/
public static void stofRef_Momory_Enough(){
    Object o1=new Obect();
    SoftReferenceObject> softReerence = new SoftReference>(o1);
    o1=null;
    System.gc();
}

/**
内存不足时 软引用会回收  (-xms5m -Xmx5m -xx:PrintGcDetails)
*/
public static void stofRef_Momory_NotEnough(){
    Object o1=new Obect();
    SoftReferenceObject> softReerence = new SoftReference>(o1);
    o1=null;
    System.out.println(softRefere.get());
    o1=null;
    try{
        byte[] bytes =new byte[30 * 1024 * 1024]
    }catch(Throwable e){
        e.pintStacTrace();
    }finally{
        System.out.println(o1);
        System.out.println(softRefere.get());
    }

}

弱引用:不管内存是否够用 只要有gc一定回收

弱引用需要用java.lang.ref.WeakReference类来实现 他比软引用的生存期更短

对于只有弱引用的对象来说 只要垃圾回收机制一运行 不管JVM的内存空间是否足够 都会回收该对象占用的内存

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());

        o1=null;
        System.gc();
          
        System.out.println(o1);
        System.out.println(weakReference.get());
    }
}

软引用和弱引用的适用场景

软引用:

假如有一个应用需要读取大量的本地图片

       如果每次读取图片都从硬盘读取则会严重影响性能

       如果一次性全部加载到内存中又可能造成内存溢出

此时使用软引用来解决这个问题。

设计思路是:用一个HashMap来保存图片的路径和相应图片对象的软引用之间的映射关系 在内存不足时 JVM会自动回收这些内存图片对象所占用的空间 从而避免oom的问题

Map<String,SoftReference<Bitmap>> imageCache=new HashMap<String,SoftReference<Bitmap>>();

WeakHashMap:

WeakHashMap<Integer ,String> map =new WeakHashMap<>();
Integer key=new Integer(1);
String value = "HashMap";
map.put(key , value);
key=null;
System.gc();
System.out.println(map);//清空

虚引用:

需要java.lang.ref.PhantomReference类来实现

顾名思义 就是形同虚设 与其他引用都不同 虚引用并不会决定对象的生命周期

如果一个对象仅保持有虚引用 那么他就和没有任何引用一样 在任何时候都可能被垃圾回收 他不同蛋蛋也不能通过他访问对象 虚引用必须和引用队列(ReferenceQueue)联合使用

虚引用的主要作用是跟踪对象被垃圾回收的状态仅仅是提供了一种确保对象被finalize以后 做事情的机制

PhantomReference的get方法总是返回null 因此无法访问对应的引用对象 其意义在于说明 一个对象已经进入finalization阶段 可以被gc回收 用来实现比finalization机制更加灵活的回收操作

换句话说 设置虚引用关联的唯一目的 就是在这个对象被垃圾回收器回收的时候手袋一个系统通知或者后续添加进一步的处理

java技术允许使用finalize()方法在垃圾谁手气将这个对象从内存清除出去之前做必要的清理工作

引用队列(软引用):

Object o1=new Object();
RefereceQueue<Object> refereQueue = new RefenceQueue();
WeakReference<Object> weakReference =new WeakReference<>(o1,referenceQueue);
System.out.println(o1);
System.out.println(weakRerenceQueue.get());
System.out.println(rerenceQueue.poll());

o1=null;
System.gc();
Thread.sleep(500);
System.out.println(o1);//null
System.out.println(weakRerenceQueue.get());//null
System.out.println(rerenceQueue.poll());//回收之前都会放入引用队列里面

引用队列(虚引用):

Object o1=new Object();
RefereceQueue<Object> referenceQueue = new RefenceQueue();
PhantomReference<Object> phantomReference =new PhantomReference<>(o1,referenceQueue);
System.out.println(o1);
System.out.println(phantomReference.get());//null
System.out.println(referenceQueue.poll());//null

o1=null;
System.gc();
Thread.sleep(500);
System.out.println(o1);//null
System.out.println(phantomReference.get());//null
System.out.println(referenceQueue.poll());//回收之前都会放入引用队列里面

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值