JVM的垃圾回收

Java中的堆是JVM所管理的最大的一块内存空间,主要用于存放各种类的实例对象在Java中堆被划分成两个不同的区域:新生代(Yong),老年代(Old)。新生代(Yong)又被划分成三个区域:Eden,From Survivor,To Survivor这样划分的目的是为了使JVM能更好的管理内存中的对象,包括内存的分配以及回收。
堆的内存模型大致为:
这里写图片描述
堆大小=新生代+老年代

GC类型分为Scanvenge GC和Full GC
年轻代的GC叫Young GC,有时候也叫Minor GC。年老代或者永久代的GC,叫Full GC,也叫 Major GC。Minor GC 是发生在新生代中的垃圾收集动作,所采用的是复制算法。Full GC 是发生在老年代的垃圾收集动作,所采用的是标记-清除算法。
新生代几乎是所有 Java 对象出生的地方,即 Java 对象申请的内存以及存放都是在这个地方。Java 中的大部分对象通常不需长久存活,具有朝生夕灭的性质。当一个对象被判定为 “死亡” 的时候,GC 就有责任来回收掉这部分对象的内存空间。新生代是 GC 收集垃圾的频繁区域。当对象在 Eden ( 包括一个 Survivor 区域,这里假设是 from 区域 ) 出生后,在经过一次 Minor GC 后,如果对象还存活,并且能够被另外一块 Survivor 区域所容纳( 上面已经假设为 from 区域,这里应为 to 区域,即 to 区域有足够的内存空间来存储 Eden 和 from 区域中存活的对象 ),则使用复制算法将这些仍然还存活的对象复制到另外一块 Survivor 区域 ( 即 to 区域 ) 中,然后清理所使用过的 Eden 以及 Survivor 区域 ( 即 from 区域 ),并且将这些对象的年龄设置为1,以后对象在 Survivor 区每熬过一次 Minor GC,就将对象的年龄 + 1,当对象的年龄达到某个值时 ( 默认是 15 岁,可以通过参数 -XX:MaxTenuringThreshold 来设定 ),这些对象就会成为老年代。
但这也不是一定的,对于一些较大的对象 ( 即需要分配一块较大的连续内存空间 ) 则是直接进入到老年代。
现实的生活中,老年代的人通常会比新生代的人 “早死”。堆内存中的老年代(Old)不同于这个,老年代里面的对象几乎个个都是在 Survivor 区域中熬过来的,它们是不会那么容易就 “死掉” 了的。因此,Full GC 发生的次数不会有 Minor GC 那么频繁,并且做一次 Full GC 要比进行一次 Minor GC 的时间更长。
另外,标记-清除算法收集垃圾的时候会产生许多的内存碎片 ( 即不连续的内存空间 ),此后需要为较大的对象分配内存空间时,若无法找到足够的连续的内存空间,就会提前触发一次 GC 的收集动作。
总的来说:
1.Scavenge GC:当新对象生成,并且在Eden区申请失败的时候将会出发Scavenge GC。将会遍历整个Eden区,将活动的对象移到Survivor区,回收不活动的对象。并整理两个Survivor区。
2.Full GC:遍历整个堆,包括年轻代,年老代和持久代。速度比Scanvenge GC慢很多,所以尽量减少Full GC.
造成Full GC的原因:年老代被写满、持久代被写满、显示调用System.GC、上一个GC后个heap的各域分配策略动态变化
垃圾回收的几种基本算法:
1.引用计数
此对象有一个引用,则增加一个计数,删除一个引用,则减少一个计数。当计数为零的时候,则是无用对象,将被回收。缺陷:无法处理循环引用的问题,并且计数器增加了程序执行的开销。
2.标记-清除
使用了根集的概念。垃圾回收器从根集开始扫面,识别出哪些对象可达,哪些对象不可达。并用某种方式标记可达对象,例如对每个可达对象设置一个活多个位。将未被标记的对象删除。缺陷:要暂停整个应用,并会产生内存碎片。
3复制
为了解决堆碎片问题。将内存分成两部分,每次便利使用区域,将活动的对象复制到另一区域,然后回收剩下的对象。同时堆复制过去以后还能进行相应的内存整理,这样就不会出现内存碎片问题。缺陷:需要更多的内存空间。
4标记-整理
此算法结合了标记-清除和复制的有点。分成两个阶段,第一个阶段从根节点开始标记所有活动对象。第二阶段遍历整个堆,清除未标记对象并将标记对象“压缩”到堆的其中一块,按顺序排放。此算法避免了碎片问题且不需要额外的内存空间。
5增量收集
实时垃圾回收算法。在应用进行的同时进行垃圾回收。
6分代
基于对对象生命周期分析后得出的垃圾回收算法。把对象分为年轻带,年老代,持久带。对不同生命周期的对象使用不同的算法(上述方式中的一种)进行回收。
年轻代:包括一个Eden区,两个Survivor区。大部分对象在Eden区生成,当Eden区满时,还存活的对象将移到Survivor区(两个Survivor区中的一个),当这个Survivor区也满时,还存活的对象将移到另一个Survivor区,当这个Survivor也满时,从第一个Survivor区来的对象还存活的话,就移到老年代。注意:链各个Survivor区没有先后关系,是对称的,总有一个是空的。
年老代:存放从年轻代移过来的对象,存活的都是比较久的对象。
持久代:用于存放静态文件,如java类,方法等。持久带对垃圾回收没有显著地影响
垃圾回收器:串行收集器,并行收集器,并发收集器
参考

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值