(二)JVM内存管理——从强引用弱引用看垃圾回收

回顾

1)JVM中引用存在哪里?

答:虚拟机栈,该内存空间线程独有

2)该引用的对象存在哪里?

答:堆,所有通过new方法分配的对象都存在堆中

3)String s1="abc",字符串"abc"存在哪里?
答:运行时常量池,且常量池每次存储对象时会查找是否存过相等的对象,如果有,直接引用指向它,不再开辟空间。

如果你三个问题都可以回答出来,恭喜你!上一篇的精髓你get到了~~~~

引用的分类

1) 强引用,默认分配方式均为此类型

Object a=new Object();

2) 软引用,以强引用为参数,构造弱引用

Object a=new Object();
SoftReference<Object> b=new SoftReference<Object>(a);
a=null;   //强引用a一定要断掉
System.out.println(b.get()); //通过get()方法返回对象

3) 弱引用

Object a=new Object();
WeakReference<Object> b=new WeakReference<Object>(a);
a=null;   //强引用a一定要断掉
System.out.println(b.get()); //通过get()方法返回对象
System.gc();

4)幽灵引用,和没有引用是一样的

引用的特点(看垃圾回收)

1)有强引用指向的对象不会被垃圾回收

2)软引用指向的对象在堆的空间不够时被回收

3)只要系统执行垃圾回收,就会回收软引用

从上面三点中,我们总结出垃圾回收是也是JVM中的一个线程,每执行一次,都要检查对象有没有强引用指向

如果没有再依次考虑软引用和弱引用

那么怎么检查呢?

代码分析


垃圾回收检查算法

1) 计数分析

每个对象,都给一个计数器,每增加一个强引用,就把计数器+1,如果当前计数器的值为0,就回收

思路很简单,但是会发生问题

Object a = new Object(); // a的引用计数为1
Object b = new Object(); // b的引用计数为1
 
a.next = b; // b的引用计数为2
b.next = a; // a的引用计数为2
 
a = null; // a的引用计数为1,尽管已经显示地将a赋值为null,但是由于引用计数为1,GC无法回收a
b = null; // b的引用计数为1,同理,GC也不回收b

2) 可达性分析

GC Root往下搜索,如果该对象是可达的,找到到达该对象的最短路径

最短路径中的强度最弱的引用,决定了该对象是否被回收

如,GC Root-(弱引用)->1对象-(强引用)->5对象

那么上述两个对象都是要被回收的

      .PS

GC Root 是什么?一些特殊的对象

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象,往往是方法中的一些简单类型变量
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值