jvm垃圾回收

为什么需要垃圾回收?

​ 首先这个问题的话,主要因为内存是计算机中比较宝贵的财富,如果堆积的对象过多,可想而知,内存会用尽,出现内存溢出的问题,这也就是为什么需要垃圾回收的原因。

对什么区域进行回收?

​ jvm中的内存结构中,虚拟机栈,本地方法栈,程序计数器随着线程的创建而创建,随着线程的销毁而销毁,因此这三个区域是不需要垃圾回收的,需要注意的是程序计数器是唯一一个不存在oom异常的,具体是因为程序计数器只需要存储线程上下文切换的行号等消耗较小的内存地址,内存分配是可见的。只存下一个字节码指令的地址,消耗内存小且固定,无论方法多深,他只存一条。

​ 因此垃圾回收区域不言而喻,那就是方法区了。

如何判断是否需要回收?

​ 判断对象是否需要回收,根据引用进行判断。主要有两种策略:引用计数法可达性分析两种策略。但是两种策略都是基于对象引用的。

引用计数法具体而言就是,每个对象都会存储着被引用的次数,如果被引用就引用次数就会+1,如果没有被引用,那就是需要被回收的对象了。但是这种方法存在这样的问题,A.instance=B;B.instance=A;循环引用,那这个怎么判断呢?因此这种方法不是很实用,因此引出可达性分析这个策略。

可达性分析也就是从根节点(常量池中的static,final,虚拟机栈中,所有被同步锁synchronized的对象等),如果当前对象被引用,那么连接一条线。如果存在没有被引用的对象,那么可达性分析,肯定是不可达的,因此该对对象就是被回收的。
上述提到的引用在jdk1.2后出现了细粒度的引用名词。强引用,软引用,弱引用,虚引用。四种引用的区别参考强引用、软引用、弱引用、虚引用的区别和作用,以及例子

如何进行回收?

​该阶段是完成了判断哪些对象是死的,哪些对象是活的之后,进行的阶段。该阶段目前有四种策略:标记清除标记复制标记整理分代收集策略。

标记清除:分为先标记再清除两个步骤。标记的话,根据可达性分析,判读出哪些对象是活的,哪些对象是死的,完成死活的标记;标记完毕之后,对死去的对象完成清除。此策略是Lisp之父提出来的,但是存在这样的问题:在清除后,出现了大量的内存碎片,在写入数据的时候会随机写入,随机写入造成的问题就是会出现大对象可能到小的区域里了,装的对象少了,那么垃圾回收的频率也会高了,垃圾回收频率高的话,系统的性能肯定会有影响。

标记复制: 分为先标记然后完成从from幸存区到to幸存区存活对象的复制。首先值得注意的是,该策略将内存一分为二。其次即使先进行死活对象的标记,标记后,将活的的对象复制到另一个区域,然后清除都是死的对象。这种方法操作起来肯定是很快的,但是问题是啥呢?那就是将内存区域一分为二了**。内存利用率是不高的

标记整理: 分为先标记再整理两个步骤。同样也先进行标记,将活的和死的进行标记。然后将死的统一清除掉,将活的对对象完成整理,也就是将其内存的地址整理为连续的地址。这种方法会涉及到移动对象,在移动的过程中会STW,如果移动的时间越长,那STW越久,弊端可想而知,影响业务。

​ 移动和不移动都会存在问题,移动了,STW时间更久,不移动,内存碎片!看看分代收集方法能否解决移动和不移动存在的问题。

分代收集: 将堆中区域分为新生代和老年代,由于大量对象的创建都是在新生代中的伊甸园区,根据这个现象,可以使用标记复制策略,也就是先进行标记,然后将存活的对象完成从幸存区from到to区转移,这样能够加快处理效率。而老年代呢?老年代存在的对象大多数都是不容易被回收的对象,也就是活着的对象,使用标记清除或者标记整理方法都是可以的,也就是说将死活的对象标记出,将少量的死对象清除。

这里存在个问题?如何进入老年代。

进入老年代的条件很简单。1)如果是大对象,直接进入老年代。为啥?因为新生代和老年代的比例为1:2。新生代如果存储的都是大对象,来个大对象,完成一次轻量级gc,随着大对象频繁的插入,轻量gc频率增大,系统就会完犊子。2)如果对象头的分代年龄达到15,那么就进入老年代。为啥是15,可以说工业级和学术界的在测试环境下,测试到15代是一个合理的数值。分代年龄如何计算的呢?一次轻量gc,分代年龄就+1。

参考资料
[1]强引用、软引用、弱引用、虚引用的区别和作用,以及例子

[2] 深入理解java虚拟机 JVM高级特性与最佳实践

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值