JVM垃圾回收

JAVA程序运行流程

在这里插入图片描述

JVM数据区组成

在这里插入图片描述

会发生内存泄漏: 虚拟机栈、本地方法栈、堆

堆内存异常

不断的New对象,当最后一个对象创建后,无法为其分配内存空间

栈内存异常

不断有变量创建,造成栈内存满


垃圾回收机制

一、首先判断清理哪些内容

垃圾回收前要判断一个对象是否存活,哪些死去。

引用计数器算法(Python):

给每个对象添加一个计数器,当有一个引用时,计数器+1,引用失效,计数器-1。为0时,说明没有引用。但是没办法解决对象之间循环引用。

可达性分析算法(JVM):

通过一个称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链。当 GC Roots 到这个对象不可达时,证明该对象不可用,可以被清理。

可作为GC Roots 的对象包括下面几类:

  • 虚拟机栈中引用的对象,(局部变量)
  • 本地方法栈(JNI)引用的对象
  • 方法区中的一些常量引用的对象

四种引用:在这里插入图片描述

二、其次怎么清理

标记清除算法

在这里插入图片描述

根据可达性分析算法得出哪些对象可以被回收,然后进行标记清除。

缺点:

​ 1、这样清理后,在内存中会有很多零散的内存碎片,浪费内存

​ 2、标记清除的效率并不高

标记整理算法

在这里插入图片描述

同样对可回收的对象进行标记后,进行分区整理,然后统一回收。

复制算法

在这里插入图片描述

在内存中会复制一份容量相同大小的内存区域,当要回收时,将存活的对象依次存入预留区,然后清空之前存放区的对象,并将之前的存放区–>预留区。

缺点:很明显解决了之前内存不足的问题,并且效率也高。但是会额外占用一块空闲区,空间利用率很低。如1G的内存只有512M可用。

分代垃圾回收算法

分代垃圾回收算法其实就是对内存回收做了分区,并结合了上面的算法。

  • 年轻代

    。Eden(伊甸)区

    。Survivor(存活)区

    ​ --from区 --to区 结合了复制算法,一个作为存储区,一个作为预留区。
    在这里插入图片描述

    在Eden区中经过可达性算法得到存活的对象,存入Survivor区,并且记录对象被引用的次数,然后清空Eden区。当记录的引用次数超过15次时,转入老年代。

    Survivor区中的对象失效后,会将from区中存活的对象利用复制算法放到to区中。

  • 老年代

    存储存活率较高的内存对象。

在这里插入图片描述

​ 老年代中的对象存活率高,所以直接采用标记清除算法、标记整理算法进行清除。

​ 当新生代中内存不够时,直接转为进入老年代。

​ 当老年代中内存不够时,直接full GC (回收整个堆的内存垃圾),会停止所有工作的线程。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值