JVM垃圾回收

        垃圾回收是当我们的线程结束之后,线程自己结束了,但是他不会将自己产生的一些线程私有的程序计数器、虚拟机栈以及本地方法栈带走,所以我们就需要将这些垃圾进行回收。但是在进行回收的时候我们要判断,哪些是已经真正的结束的对象,然后对他们进行回收。
一、判断结束对象
1、引用计数器算法
        我们给每一个对象加上一个计数器,当我们用的时候计数器加一,不同的时候计数器减一,当计数器为0的时候就表示不再被使用,是一个已经需要被回收的对象。但是引用计数器算法不能解决对象循环引用的问题(a引用了b,b引用了a,没有线程在使用a和b但是因为他们互相引用就不能进行垃圾回收)
2、可达性分析算法
        可达性算法是找到一种可以做“GC Roots”的对象,然后从这个结点开始向下搜索,在搜索过程中走过的路径叫做引用链,然后这个引用链上的都是不需要进行垃圾回收的,当所有的引用链都没有经过的对象就是需要进行垃圾回收的对象。那么问题来了我们怎么确定谁可以作为“GC Roots”对象,虚拟机栈中的引用对象、元数据区中类静态属性引用的对象、元数据区中常量引用的对象(常量池中的对象)、本地方法栈中的引用对象,这四类都可以作为我们的“GC Roots”对象。
        我们也可以利用引用判断需要垃圾回收的对象,引用共分为四类,强引用、软引用、弱引用、虚引用。
强引用:在程序中普遍存在的,强引用的对象永远不会被垃圾回收掉。(我们直接new出来的对象就是强引用对象)
软引用:表示可以但没必要的对象,软引用关联的对象是在内存快溢出之前,将这些对象会标识为下一次垃圾回收的对象。
弱引用:表示比软引用更不需要的对象,这类对象,会在下一次垃圾回收的时候直接被回收掉,不管内存是不是快溢出了。
虚引用:是一种最弱的关系,一个对象有没有虚引用不会对它的生存时间产生影响,并且我们也没有办法用一个虚引用来获取一个对象的实例。虚引用存在的意义是能在对象被垃圾回收的时候收到一个通知。

二、垃圾回收算法
1、标记清楚算法
        也就是先将需要回收的对象进行标记,然后统一将所有标记了的对象进行回收。
在这里插入图片描述
        我们看这个图有一个很明显的问题就是我们的内存零零碎碎的,他没有进行内存的整理,所以出现了内存碎片的问题。

2、复制算法
        复制算法是将我们的内存分为两个区域,每次使用一半,另一半作为保留的区域,再进行垃圾回收的时候,我们先把不需要回收的对象复制到保留的区域,然后再把使用的那一半区域一次性全部清除掉。
在这里插入图片描述
        复制算法的性能非常高,但是内存的利用率很低,因为存在内存的保留区。

3、标记整理算法
        他和标记清楚算法很像,只是多了一个整理的步骤。还是先标记,然后清除,边清除,边将保留的对象向一边移动。
在这里插入图片描述
        这样就解决了内存碎片的问题,同时还不会减少内部承诺的利用率。但是他的效率比较低。

4、分代算法
        分代算法不是一种具体的算法,它像是一种策略,就是将区域进行划分,分为新生代和老年代,新生代追求的是效率,那么就可以使用复制算法,老年代的存活率很高,那么就需要使用标记清除或者标记整理的算法。

三、新生代和老年代
新生代:刚创建的对象就会先进入新生代
老年代:经过15次(一般情况下为15次,也不是固定的)垃圾回收之后还存在的对象就会进入老年代,还有一种特殊的情况就是一个很大的对象,他也会直接进入老年代里。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值