`
javayestome
  • 浏览: 1041681 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

非常详细GC学习笔记

阅读更多

这是我公司同事的GC学习笔记,写得蛮详细的,由浅入深,循序渐进,让人一看就懂,特转到这里。

GC学习笔记

一、GC特性以及各种GC的选择

1、垃圾回收器的特性

2、对垃圾回收器的选择

2.1连续VS.并行

2.2并发VS.stop-the-world

2.3压缩VS.不压缩VS.复制

二、GC性能指标

三、分代回收

四、J2SE5.0HotSpotJVM上的GC学习-分代、GC类型、快速分配

五、J2SE5.0HotSpotJVM上的GC学习-SerialGC

六、J2SE5.0HotSpotJVM上的GC学习-ParallelGC

七、J2SE5.0HotSpotJVM上的GC学习-ParallelCompactingGC

八、J2SE5.0HotSpotJVM上的GC学习-CMSGC

九、启动参数学习示例

一、GC特性以及各种GC的选择

1垃圾回收器的特性

·该回收的对象一定要回收,不该回收的对象一定不能回收

·一定要有效,并且要快!尽可能少的暂停应用的运行

·需要在时间,空间,回收频率这三个要素中平衡

·内存碎片的问题(一种解决内存碎片的方法,就是压缩)

·可扩展性和可伸缩性(内存的分配和回收,不应该成为跑在多核多线程应用上的瓶颈)

2对垃圾回收器的选择

2.1连续VS.并行

连续垃圾回收器,即使在多核的应用中,在回收时,也只有一个核被利用。
但并行GC会使用多核,GC任务会被分离成多个子任务,然后这些子任务在各个CPU上并行执行。
并行GC的好处是让GC的时间减少,但缺点是增加了复杂度,并且存在产生内存碎片的可能。

2.2并发VS.stop-the-world

当使用stop-the-world方式的GC在执行时,整个应用会暂停住的。
而并发是指GC可以和应用一起执行,不用stoptheworld

一般的说,并发GC可以做到大部分的运行时间,是可以和应用并发的,但还是有一些小任务,不得不短暂的stoptheworld

stoptheworldGC相对简单,因为heap被冻结,对象的活动也已经停止。但缺点是可能不太满足对实时性要求很高的应用。
相应的,并发GCstoptheworld时间非常短,并且需要做一些额外的事情,因为并发的时候,对象的引用状态有可能发生改变的。
所以,并发GC需要花费更多的时间,并且需要较大的heap

2.3压缩VS.不压缩VS.复制

GC确定内存中哪些是有用的对象,哪些是可回收的对象之后,他就可以压缩内存,把拥有的对象放到一起,并把剩下的内存进行清理。
在压缩之后,分配对象就会快很多,并且内存指针可以很快的指向下一个要分配的内存地址。

一个不压缩的GC,就原地把不被引用的对象回收,他并没有对内存进行压缩。好处就是回收的速度变快了;缺点呢,就是产生了碎片。

一般来说,在有碎片的内存上分配一个对象的代价要远远大于在没有碎片的内存上分配。

另外的选择是使用一个复制算法的GC,他是把所有被引用的对象复制到另外一个内存区域中。
使用复制GC的好处就是,原来的内存区域,就可以被毫无顾忌的清空了。但缺点也很明显,需要更多的内存,以及额外的时间来复制。

二、GC性能指标

窗体底端

几个评估GC性能的指标

·吞吐量应用花在非GC上的时间百分比

·GC负荷与吞吐量相反,指应用花在GC上的时间百分比

·暂停时间应用花在GCstop-the-world的时间

·GC频率顾名思义

·Footprint一些资源大小的测量,比如堆的大小

·反应速度从一个对象变成垃圾道这个对象被回收的时间

一个交互式的应用要求暂停时间越少越好,然而,一个非交互性的应用,当然是希望GC负荷越低越好。
一个实时系统对暂停时间和GC负荷的要求,都是越低越好。
一个嵌入式系统当然希望Footprint越小越好。

三、分代回收

窗体底端

什么是分代

当使用分代回收技术,内存会被分为几个代(generation)。也就是说,按照对象存活的年龄,把对象放到不同的代中。

使用最广泛的代,应属年轻代和年老代了。

根据各种GC算法的特征,可以相应的被应用到不同的代中。

研究发现:

·大部分的对象在分配后不久,就不被引用了。也就是,他们在很早就挂了。

·只有很少的对象熬过来了。

年轻代的GC相当的频繁,高效率并且快。因为年轻代通常比较小,并且很多对象都是不被引用的。

如果年轻代的对象熬过来了,那么就晋级到年老代中了。如图:

通常年老代要比年轻代大,而且增长也比较慢。所以GC在年老代发生的频率非常低,不过一旦发生,就会占据较长的时间。

总结

·年轻代通常使用时间占优的GC,因为年轻代的GC非常频繁

·年老代通常使用善于处理大空间的GC,因为年老代的空间大,GC频率低

四、J2SE5.0HotSpotJVM上的GC学习-分代、GC类型、快速分配

窗体底端

J2SE5.0update6HotSpot上有4GC

HotSpot上的分代

分成三部分:年轻代、年老代、永久代

很多的对象一开始是分配在年轻代的,这些对象在熬过了一定次数的younggc之后,就进入了年老代。同时,一些比较大的对象,一开始就可能被直接分配到年老代中(因为年轻代比较小嘛)。

年轻代

年轻代也进行划分,划分成:一个Eden和两个survivor。如下图:

大部分的对象被直接分配到年轻代的eden区(之前已经提到了是,很大的对象会被直接分配到年老代中),
survivor区里面放至少熬过一个YGC的对象,在survivor里面的对象,才有机会被考虑提升到年老代中。

同一时刻,两个survivor只被使用一个,另外一个是用来进行复制GC时使用的。

GC类型

年轻代的GCyoungGC,有时候也叫minorGC。年老代或者永久代的GC,叫fullGC,也叫majorGC

也就是说,所有的代都会进行GC

一般的,首先是进行年轻代的GC,(使用针对年轻代的GC),然后是年老代和永久代使用相同的GC。如果要压缩(解决内存碎片问题),每个代需要分别压缩。

有时候,如果年老区本身就已经很满了,满到无法放下从survivor熬出来的对象,那么,YGC就不会再次触发,而是会使用FullGC对整个堆进行GC(除了CMS这种GC,因为CMS不能对年轻代进行GC

快速分配内存

多线程进行对象建立的时候,在为对象分配内存的时候,就应该保证线程安全,为此,就应该进入全局锁。但全局锁是非常消耗性能的。

为此,HotSpot引入了ThreadLocalAllocationBuffersTLAB)技术,这种技术的原理就是为每个线程分配一个缓冲,用来分配线程自己的对象。

每个线程只使用自己的TLAB,这样,就保证了不用使用全局锁。当TLAB不够用的时候,才需要使用全局锁。但这时候对锁的时候,频率已经相当的低了。

为了减少TLAB对空间的消耗,分配器也想了很多方法,平均来说,TLAB占用Eden区的不到1%

五、J2SE5.0HotSpotJVM上的GC学习-SerialGC

窗体底端

串行GC

串行GC,只使用单个CPU,并且会stoptheworld

young的串行GC

如下图:


当发生ygc的时候,EdenFromsurvivor区会将被引用的对象复制到To这个survivor种。
如果有些对象在Tosurvivor放不下,则直接升级到年老区。

YGC完成后,内存情况如下图:

old区的串行GC

年老区和永久区使用的是Mark-Sweep-Compact的算法。

mark阶段是对有引用的对象进行标识
sweep是对垃圾进行清理
compact对把活着的对象进行迁移,解决内存碎片的问题

如下图:

何时使用串行收集器

串行GC适用于对暂停时间要求不严,在客户端下使用。

串行收集器的选择

J2SE5.0上,在非server模式下,JVM自动选择串行收集器。

也可以显示进行选择,在java启动参数中增加:-XX:+UseSerialGC

六、J2SE5.0HotSpotJVM上的GC学习-ParallelGC

窗体底端

并行GC

现在已经有很多java应用跑在多核的机器上了。

并行的GC,也称作吞吐量GC,这种GC把多个CPU都用上了,不让CPU再空转。

YGC的并行GC

YGC的情况,还是使用stop-the-world+复制算法的GC

只不过是不再串行,而是充分利用多个CPU,减少GC负荷,增加吞吐量。

如下图,串行YGC和并行YGC的比较:

年老区的并行GC

也是和串行GC一样,在年老区和永久区使用Mark-Sweep-Compact,利用多核增加了吞吐量和减少GC负荷。

何时使用并行GC

对跑在多核的机器上,并且对暂停时间要求不严格的应用。因为频率较低,但是暂停时间较长的FullGC还是会发生的。

选择并行GC

server模式下,并行GC会被自动选择。
或者可以显式选择并行GC,加启动JVM时加上参数:-XX:UseParallelGC

七、J2SE5.0HotSpotJVM上的GC学习-ParallelCompactingGC

ParallelCompactingGC

parallelCompactingGC是在J2SE5.0update6引入的。

parallelcompactingGCparallelGC的不同地方,是在年老区的收集使用了一个新的算法。并且以后,parallelcompactingGC会取代parallemGC的。

YGC的并行压缩GC

与并行GC使用的算法一样:stop-the-world和复制。

年老区的并行压缩GC

他将把年老区和永久区从逻辑上划分成等大的区域。
分为三个阶段:

1标记阶段,使用多线程对存在引用的对象进行并行标记。

2分析阶段,GC对各个区域进行分析,GC认为,在经过上次GC后,越左边的区域,有引用的对象密度要远远大于右边的区域。所以就从左往右分析,当某个区域的密度达到一个值的时候,就认为这是一个临界区域,所以这个临界区域左边的区域,将不会进行压缩,而右边的区域,则会进行压缩。

3压缩阶段,多各个需要压缩的区域进行并行压缩。

什么时候使用并行压缩GC

同样的,适合在多核的机器上;并且此GCFGC的时候,暂停时间会更短。

可以使用参数-XX:ParallelGCThreads=n来指定并行的线程数。

开启并行压缩GC

使用参数-XX:+UseParallelOldGC

八、J2SE5.0HotSpotJVM上的GC学习-CMSGC

ConcurrentmarksweepGC

很多应用对响应时间的要求要大于吞吐量。
YGC并不暂停多少时间,但FGC对时间的暂用还是很长的。特别是在年老区使用的空间较多时。
因此,HotSpot引入了一个叫做CMS的收集器,也叫低延时收集器。

CMSYGC

与并行GC同样的方式:stop-the-world加上copy

CMSFGC

CMSFGC在大部分是和应用程序一起并发的!
CMSFGC的时候,一开始需要做一个短暂的暂停,这个阶段称为最初标记:识别所有被引用的对象。
在并发标记时候,会和应用程序一起运行。
因为并发标记是和程序一起运行的,所以在并发标记结束的时候,不能保证所有被引用的对象都被标记,
为了解决这个问题,GC</span

分享到:
评论
2 楼 56553655 2011-11-13  
这个格式是好的:http://blog.csdn.net/fenglibing/article/details/6321453
1 楼 Willam2004 2011-07-09  
为什么在ubuntu下的chrome下预览,格式都乱了?

相关推荐

    JVM学习笔记(一)

    ### JVM学习笔记(一) #### 一、JVM概述与工具使用 JVM(Java Virtual Machine)是...以上是JVM的基本使用技巧和常用工具的详细介绍,这些工具对于Java开发者来说非常实用,可以帮助我们更好地理解和优化JVM的性能。

    Go 学习笔记 第四版.pdf

    本资源是一个详细的 Go 编程语言学习笔记,涵盖了 Go 语言的基本语法、数据类型、函数、goroutine、channel、reflect 等多方面的知识点。 一、基本语法 * 变量声明:Go 语言中可以使用 var 关键字声明变量,例如 `...

    良葛格Java学习笔记

    【良葛格Java学习笔记】 本笔记主要涵盖了Java编程语言的核心概念和技术,旨在帮助初学者以及有一定基础的开发者深入理解并掌握Java。Java作为一种广泛应用于企业级应用开发、移动开发(尤其是Android)以及大数据...

    java se学习笔记

    【Java SE学习笔记】是针对Java初学者的一份详实的学习资源,主要涵盖了Java的基础知识、进阶概念以及编程实践。这份笔记以HTML格式呈现,方便读者在线阅读或下载后离线浏览。以下是对这份笔记可能包含的重要知识点...

    5G-QoS-学习笔记.pdf

    (一) Qos mapping的流程 1. 信令流程 1) SMF从PCF/PCC等网元获取Qos信息; 2) UE或者AN发起PDU session modification过程,AMF转发给SMF; 3) SMF对AMF响应Nsmf_PDUSession_UpdateSMContext消息,这个消息中包含: ...

    JAVA SE学习笔记

    **JAVA SE学习笔记** 在Java SE(标准版)的学习中,我们主要关注的是Java编程语言的基础和核心特性,包括但不限于语法、数据类型、控制结构、类与对象、接口、异常处理、多线程、集合框架、输入/输出(I/O)系统、...

    JVM学习笔记

    ### JVM学习笔记 #### JVM内存模型 (JMM) JVM内存模型主要分为以下几个部分: - **Java堆**:这是所有线程共享的一块区域,在虚拟机启动时创建。主要用于存放对象实例,几乎所有的对象实例都在这里分配内存。 - *...

    go学习笔记 第四版

    ### Go语言学习笔记知识点概述 #### 一、Go语言简介 - **Go语言起源与发展历程**:Go语言是由Google在2009年发布的一种开源编程语言,旨在提高开发效率和程序性能。从2012年开始,Go语言经历了多个重要版本的迭代...

    阿里P8 架构师整理Java学习笔记.pdf

    ### Java学习笔记知识点总结 #### 一、JVM与内存管理 **1.1 JVM基本概念** - **JVM(Java Virtual Machine)**: Java虚拟机是执行Java字节码的虚拟机,它提供了运行Java程序所需的环境。 **1.2 线程** - **线程...

    Java学习笔记_垃圾回收

    Java垃圾回收(Garbage Collection, 简称GC)是Java编程语言中一项重要的自动内存管理机制,...通过阅读"Java学习笔记_垃圾回收.pdf",你将进一步深入理解这个主题,掌握如何在实际项目中有效利用和优化垃圾回收机制。

    java学习笔记4

    以上内容是基于“java学习笔记4”的标题和描述所推测的可能知识点,具体的学习内容需参考“video4”这个压缩包文件中的详细资料。对于初学者和有经验的开发者来说,这些知识点都是非常有价值的。

    AWB学习笔记

    关于手机camera方面的AWB学习笔记,主要讲述GC0329的AWB

    学习笔记——资料

    【Java学习笔记——全面解析】 Java作为一种广泛应用的高级编程语言,是软件开发领域的核心力量。这份"学习笔记——资料"涵盖了Java学习的各个方面,旨在帮助初学者和有经验的开发者巩固基础,提升技能。以下是对这...

    Go学习笔记

    在学习Go语言的过程中,会涉及到多个方面的知识点,比如: - Go的基本语法,包括变量、类型、控制结构、函数和方法等; - Go的并发模型,以及goroutine和channel的使用; - Go的网络编程能力,支持HTTP、RPC、Socket...

    在工作中java学习资料学习笔记

    这份“在工作中Java学习资料学习笔记”旨在帮助开发者在实际项目开发中提升技能和效率。以下是一些关键知识点的详细说明: 1. **面向对象编程**:Java的核心特性是面向对象编程(OOP),它将数据和操作数据的方法...

    Java架构面试专题汇总(含答案)和学习笔记.zip

    这个压缩包包含的学习笔记和习题集全面覆盖了Java架构师所需的核心知识点,下面我们将深入探讨其中的关键内容。 1. **Java基础** - **数据类型与变量**:理解基本数据类型、引用数据类型,以及它们在内存中的存储...

    net学习笔记及其他代码应用

    Runtime.getRuntime().gc() 37.String s = new String(\"xyz\");创建了几个String Object? 答:两个对象,一个是“xyx”,一个是指向“xyx”的引用对象s。 38.abstract class和interface有什么区别? 答: 声明...

    JAVA学习笔记.zip

    【Java学习笔记.zip】是一个包含了全面的Java学习资源的压缩包,主要涵盖了Java基础知识、JVM虚拟机原理、操作系统概念、计算机网络知识以及与数据库相关的笔记。这个资料包显然是为那些刚开始学习Java编程或者准备...

    java学习笔记,好好学习

    这篇“java学习笔记”可能包含了从基础到进阶的各种Java编程概念和技术。以下是对这些笔记可能涵盖的一些关键知识点的详细说明: 1. **Java基础知识**: - **语法**:包括变量声明、数据类型(如整型、浮点型、...

Global site tag (gtag.js) - Google Analytics