JVM中的垃圾回收机制

一、前言

垃圾回收机制,首先你必须先要确定jvm中那个地方会产生垃圾,然后如何检测那些东西是垃圾,最后才能回收这些垃圾。

二、先来看看垃圾的检测

再说垃圾检测之前我们先看回顾下jvm的结构:栈、堆、程序计数器、方法区、本地方法栈。这几块内存区域中栈、本地方法栈、程序计数器属于线程,线程结束就结束,线程新建就生成,所以这里不用考虑垃圾的回收,然后是方法区,方法区里面保存的是类的基本信息等,所以这里也不用考虑,而堆,堆是类实例对象生成存储的地方,而对象存在无引用的对象,所以堆是需要垃圾回收的。

搞清楚了垃圾回收的区域,然后就需要垃圾检测,一般有这几种垃圾检测的算法:
a.引用计数法
引用计数法就是给对象一个引用计数器,有地方对他进行引用就+1,引用消失就-1,如果一个对象没有引用值,那么这个对象就是垃圾,需要回收。但是这里会有个问题,如果a、b两个对象相互引用,并没有其他的引用。那么他们的计数器即不为0,也属于需要回收的垃圾,所以这种时候就会出现问题。
b.可达性分析法
以根集对象为起始点进行搜索,如果有对象不可达的话,即是垃圾对象。这里的根集一般包括java栈中引用的对象、方法区常良池中引用的对象本地方法中引用的对象等。

三、回收垃圾

既然检测出来垃圾的存在,所以就需要来回收,回收算法一般有这几类

1.标记-清除(Mark-sweep)(标记垃圾对象,统一回收)
优点:基础算法,简单实现 缺点:效率低,产生大量碎片
这里写图片描述

2.复制(Copying)(内存分为平等2分,复制使用对象到另外一块)
优点:复制成本小、解决了碎片的问题 缺点:内存需求更多
这里写图片描述

3.标记-整理(Mark-Compact)(标记存活对象,清除为标记对象,并压缩存活对象)
这里写图片描述

4.分代收集算法( 分代的垃圾回收策略)
分代收集涉及了前面的算法。年轻代:涉及了复制算法;年老代:涉及了“标记-整理(Mark-Sweep)”的算法.
年轻代:是所有新对象产生的地方。年轻代被分为3个部分——Enden区和两个Survivor区(From和to)当Eden区被对象填满时,就会执行Minor GC。并把所有存活下来的对象转移到其中一个survivor区(假设为from区)。Minor GC同样会检查存活下来的对象,并把它们转移到另一个survivor区(假设为to区)。这样在一段时间内,总会有一个空的survivor区。经过多次GC周期后,仍然存活下来的对象会被转移到年老代内存空间。通常这是在年轻代有资格提升到年老代前通过设定年龄阈值来完成的。需要注意,Survivor的两个区是对称的,没先后关系,from和to是相对的。
年老代:在年轻代中经历了N次回收后仍然没有被清除的对象,就会被放到年老代中,可以说他们都是久经沙场而不亡的一代,都是生命周期较长的对象。对于年老代和永久代,就不能再采用像年轻代中那样搬移腾挪的回收算法,因为那些对于这些回收战场上的老兵来说是小儿科。通常会在老年代内存被占满时将会触发Full GC,回收整个堆内存。
持久代:用于存放静态文件,比如java类、方法等。持久代对垃圾回收没有显著的影响。
这里写图片描述

参考博客: http://blog.csdn.net/tonytfjing

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值