Java GC:Java GC原理

stop-the-world。这种机制会在任何一种算法中发生,GC优化即是指减少该机制发生的时间和机会。

按代的垃圾回收机制:

弱年代假设:
程序员无法在程序中直接清理内存,而是由垃圾回收器寻找不必要的垃圾对象。

  1. 大多数对象变得不可达时(即对象引用为null时),
  2. 只有很少的老年对象指向新生对象的引用时,

垃圾回收器会寻找不必要的对象并清理他们。

为了强化弱年代假设,HotSpot虚拟机(Oracle公司现用的虚拟机)在物理内存上又划分为:

  1. 新生代(Young generation):
    绝大多数最新创建的对象会被分配到此,大部分对象在创建后变的不可达,
    然后消失。这个过程被称为”minor GC”。

  2. 老年代(Old generation)
    若对象没有变为不可达,并且从新生代中存活下来,会被拷贝到此。
    这里占用的空间要比新生代多。正因如此,老年代GC要比新生代GC少。
    对象从老年代小时的过程称为”major GC”。

还有一种”major GC”发生在持久代(permanent generation)。
持久代。也被称为方法区(method area)它用来保存类常量以及字符串常量, 持久代中也可能发生GC。

card table:

发生GC后,老年代要引用一个新生代对象的时候,怎么办呢?
为了解决这一问题,老年代中存在一个” card table”
它是一个512byte大小的 块。所有老年代对象指向新生代对象时都会被记录在这个表中。
当针对新生代执行GC时,只需要查询card table来决定是否可以被回收。而不用 查询整个老年代。这个card table有一个write barrier(“屏障、栅栏”)来管理。

新生代(Young generation)minor GC处理机制:

新生代用来保存第一次被创建的对象。被分为三个空间:

一个Eden(伊甸园)空间
两个Survivor(幸存者)空间

  1. 绝大多数刚刚被创建的对象会存放在Eden空间。
  2. Eden空间执行一次GC后,存活的对象会被移动到其中一个Survivor空间。
  3. 此后,在伊甸园空间执行GC后,存活的对象会被移动到同一个Survivor空间。
  4. 当一个Survivor空间饱和时,还存在的对象会被移动到另外一个Survivor空间。
    以上步骤重复执行几次依然存活的对象,会被移动到老年代。
    如果两个Survivor空间都有数据,或者都为空,那么表明你程序出现了问题。

        HotSpot虚拟机使用了两种机制来加快内存分配(了解即可):
            1 . bump-the-pointer(“指针”)。
                检查Eden空间顶部是否存在空间。
            2 . TLABS(Thread-Local Allocation Buffers)线程本地分配缓冲区。
                针对多线程问题的解决方案。在Eden空间为每个线程分配独享空间。
    

老年代(Old generation)major GC处理机制:

major GC事件基本上是在空间已满时发生,并且根据GC类型不同而不同。
1 .Serial GC 串行GC
2 . Parallel GC 并行GC
3 . Parallel Old GC 并行压缩GC
4 . Concurrent Mark & Sweep GC 并行扫描GC
5 . Garbage First(G1) GC 垃圾优先GC

Serial GC不应该被用在服务器上。使用Serial GC会显著降低应用性能的指标。
老年代空间的GC采取称之为mark-sweep-compact的算法。

1 .Serial GC 串行GC :

第一步:标记老年代中依然存活的对象。(标记)
第二步:从头开始检查堆内存空间,并且会留下依然幸存的对象。(清理)
第三步:从头开始,顺序的填满对内存空间,并且将堆内存空间分为两部分:一个保存对象,另一个压缩。
Serial GC 串行GC是单个线程进行的。速度慢并且会降低应用程序指标。

2.Parallel GC 并行GC:

Parallel GC与Serial GC算法相同,但是Parallel GC实现了多线程处理GC。效率更高。

3.Parallel Old GC 并行压缩GC:

Parallel Old GC 在JDK5之后才出现。
与Parallel GC相比,唯一的区别在于针对老年代的GC算法。
Parallel Old GC分为三步:标记-汇总-压缩(mark -summary-compaction)。
汇总步骤与清理步骤的不同之处在于,其将依然幸存的对象分发到GC预先处理好的不同区域。算法略微复杂。

4.Concurrent Mark & Sweep GC 并行扫描GC

CMS GC 比之前的三种算法要复杂得多。
第一步初始化标记。查找那些距离类加载器最近的幸存对象。因此停顿时间非常短暂。
第二步并行标记。所有被幸存的对象引用会被确认是否已经被追踪和校验。 并且在标记的过程中其他线程依然执行。在重新标记步骤,会再次检查在并行标记步骤中增加或者删除的与幸存对象的引用对象。
第三步在并行交换步骤,转交垃圾回收过程处理。垃圾回收工作会在其他线程的执行中展开。
一旦采取这种GC,由GC导致的暂停时间见会及其短暂。
所以 也被称为低延迟GC。
它经常被用在对于响应时间要求十分苛刻的应用之上。
当然。由于多线程的问题也有以下缺点:
1.它会比其他GC类型占用更多的内存和CPU。
2.默认情况下不支持压缩步骤。
在使用Concurrent Mark & Sweep GC之前要慎重考虑。如果因为内存碎片过多而导致压缩任务不得不执行。那么stop-the-world的时间要比其他类型都要长。需要考虑压缩任务的发生频率以及执行时间。

5.Garbage First(G1) GC 垃圾优先GC

每个对象被分配到不同的格子。随后执行GC,当一个区域装满后,对象被分配到另一个区域,并执行GC。
这中间不再有新生代移到老年代的三个步骤。这个类型是为了替代CMS GC而被创建的。
因为CMS GC在长时间持续运作会产生很多问题。
G1 GC最大的好处是性能。它比任何一种GC多要快很多。但是在JDK1.6中还只是早期试用版本, 由JDK1.6的G1 GC时间导致的JVM宕机事件也时有发生。

不能因为某个应用使用的GC参数“A”,就说明同样的参数也能给其他服务带来最佳的效果。而是要因地制宜,有的放矢。

Java GC知识还有JVM结构都是以后要深入理解的内容。深入浅出。
本文只是简单总结了Java GC的基本知识。关于Java GC的观察和优化。可能在学习高并发后才会深刻体会。现在作为入门和基础。以后不至于忙手忙脚。
以下文章详细讲了GC观察和优化。包括服务器的深刻理解。
http://www.importnew.com/2057.html
http://www.importnew.com/3146.html
http://www.importnew.com/3151.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值