Java中不同引用类型的回收状态

强应用

全局变量

User mUser = new User();

如果一个对象具有强引用,那么GC绝对不会回收它,让内存空间不足,JVM宁愿抛出OOM错误使程序崩溃,也不会靠随意回收具有强引用的对象来解决内存不足问题。如果强引用对象不再使用时,需要弱化从而使GC能回收,需要把引用置为null:

mUser = null;

还有一种情况,局部变量:

public void onStrongReference() {
    User localUser = new User();
}

在onStrongReference()方法中有一个强引用,这个引用保存在java虚拟机栈中,而真正的引用对象保存在堆中。当这个方法执行完就会从java虚拟机栈中移除,则引用对象的引用数量为0,这个对象可被GC回收。

软引用(SoftReference)

如果一个对象只具有软引用,则内存空间足够,GC不会回收它;如果内存空间不足了,就会回收这些对象占用的内存,只要GC没有回收它,该对象就可以被程序继续使用。软引用可用来实现内存敏感的高速缓存。

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被GC回收,JVM就会把这个软引用加入到与之关联的引用队列中。

public void onSoftReference() {
    ReferenceQueue<User> queue = new ReferenceQueue();
    User localUser = new User();
    SoftReference<User> softReference = new SoftReference<>(localUser, queue);
    localUser = null;
    System.gc();
}

注意:软引用对象是在JVM内存不足时才会被回收,我们调用System.gc()方法只是起到通知作用,JVM什么时候扫描并回收对象内存是JVM的状态来决定的。就算扫描到localUser对象也不会回收,只有内存不足时才会回收。

若引用(WeakReference)

弱引用与软引用的区别:只有具有弱引用的对象拥有更短暂的生命周期。在GC线程扫描到它所管辖的内存区域过程中,一旦发现了只具有弱引用的对象,不管当前内存充足与否,都会回收对象所占用的内存。不过由于GC是一个优先级很低的线程,因此不一定会很快发现那些具有弱引用的对象。

弱引用可以和一个引用队列一起使用,如果弱引用所引用的对象被GC回收,JVM就会把这个弱引用加入到与之关联的引用队列中。

public void WeakReference() {
    ReferenceQueue<User> queue = new ReferenceQueue<>();
    User localUser =  new User();
    WeakReference<User> weakReference = new WeakReference(localUser, queue);
     Log.i(weakReference.get());//java.lang.ref.Object@156780
    localUser = null;
    System.gc();
    Thread.sleep(2000L);
    Log.i(weakReference.get);//null
    Log.e(queue.poll());//java.lang.ref.WeakReference@897900

}

可见软引用的对象生命周期基本由GC来决定,一旦GC线程扫描到了只有弱引用引用的对象就标记下来,第二次扫描到就直接回收。

虚引用(PhantomReference)

创建虚引用必须和引用队列关联

public void onPhantomReference() {
    User localUser = new User();
    ReferenceQueue<User>  queue = new ReferenceQueue<>();
    PhantomReference<User> phantomReference = new PhantomReference(localUser, queue);
    
}

虚引用如果它的名字一样,形同虚设,与其他几种引用不同,虚引用并不会决定对象的生命周期。如果一个对象仅有虚引用,那么就和没有任何引用一样,GC线程扫描到该对象会回收。
虚引用主要用来跟踪对象被GC回收的活动。虚引用与软引用和弱引用的区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当GC准备回收一个只有虚引用引用的对象时,就会在回收对象之前,把这个虚引用加入到与之关联的引用队列中。


总结
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,309评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 177,391评论 25 709
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 47,227评论 6 342
  • feisky云计算、虚拟化与Linux技术笔记posts - 1014, comments - 298, trac...
    不排版阅读 4,141评论 0 5
  • 2018.2.18 初三 今天是大年初三了 今年的北京感觉没什么年味了 不知道是我的内心变化了,还是外环境变化了 ...
    淅淅_fighting阅读 165评论 1 1

友情链接更多精彩内容