3 GC概念

Gc的职责:

1)  分配内存

2)  保证被引用的对象驻留内存

3)  对象不可达后将其占用内存回收

被引用对象被称为 “存活对象”。

不再被引用的对象称为“垃圾对象”。

找到垃圾对象并将其占用内存释放的过程被称为垃圾收集。

垃圾收集耗费的时间取决于选择的垃圾收集器。

大多数动态内存分配算法需要面临的问题是在搞笑分配和回收内存时如何避免碎片。

期望的垃圾收集器特征

垃圾收集器必须保证安全和全面。

不能错误地将存活对象释放,垃圾对象也要保证在几个回收轮次内回收掉。

垃圾回收要非常搞笑,不能停顿过长时间而导致应用无法运行。

一般需要在时间、空间、频率几个方面做一个权衡。

垃圾回收要限制碎片产生。通过压缩来消除碎片。

可伸缩性也非常重要。对象分配和回收不能成为多CPU系统上运行的多线程应用可伸缩性的瓶颈。

Design Choices

设计决策

1、  Serial 对 Paralle

Serial收集时,不能执行其他应用。只利用一个CPU。

并行收集,将收集任务分为多个子任务,它们在不同CPU上同时执行,速度更快,但有额外的复杂性,可能产生碎片。

2、  同步 对 暂停

Stop-the-world 垃圾收集启动期间,应用的执行会完全暂停。

并发垃圾收集器的一个或多个任务会和应用同时运行,其大部分工作都是并发执行的,但偶尔也需要短时间暂停应用执行,其需要更大的堆内存。

3、  压缩 对 不压缩 对 拷贝

识别存活对象并将其移动到一起,然后将其他不用空间释放。--压缩。

压缩后可以从第一个可用地址空间来分配对象,速度更快,更简单,用一个指针跟踪下一个

可用地址。

非压缩收集器仅仅把垃圾对象原地释放,其手机速度更快,但缺陷是产生垃圾碎片,而且分配对象更复杂。

拷贝收集器,将存活对象拷贝到一个不同的内存区,更快,更容易分配,但拷贝需要耗时,也需要额外空间。

Performance Metrics

性能度量。

评估性能。

1)  吞吐量。长时间内非gc时间的百分比

2)  Gc开销。长时间内gc时间的百分比

3)  停顿时间。Gc过程中应用暂停的时间

4)  收集频率。

5)  空间大小。占用的堆大小

6)  Promptness。即时性。对象变为垃圾数据到其内存被回收的时间。

交互性应用要求较低的停顿时间,非交互式则要求吞吐量,实时应用对gc的停顿时间和吞吐量都要求较高。

分代收集。

内存划分为几个“代”,不同的代保留不同存活时间的对象。

每个分代有适合的算法。

Weak generation hypothesis。

大多数对象存活很短

从老年代引用新生代对象的情况很少

新生代中的对象经过几次收集依然存活的会被提升到老年代。

老年代一般比新生代占比更大,增长更缓慢,收集频率低,但耗时长。

新生代垃圾收集算法着重速度,其收集频繁,老年代收集要求空间效率高。

Garbage Collectors in the J2SE 5.0 HotSpot JVM

回收算法。

Hotspot的分代:新生代,老年代,永久代。

绝大多数对象在新生代中分配。

老年代包含从新生代中提升的或者初始就非常大的对象。

永久代,包括JVM使用的元数据。

新生代由三部分构成: Eden、两个survior区。

大部分对象在eden中初始化分配。

Survivor区保留至少存活过一次收集的对象。有一个survior一直为空。

垃圾收集类型

新生代填满后,新生代开始收集(minor collection)。

老年代满了之后做major collection,此时所有的粉黛都会收集。一般会先收集新生代,

然后使用 老年代收集算法 收集老年代和永久代,如果需要压缩,每个分代都独立压缩。

但是。。。当major gc时,如果先对新生代收集,并且老年代没有足够空间容纳新生代提升上来的对象时,就不会再使用新生代收集算法,而是对所有的堆都使用 老年代收集算法。例外就是CMS收集器,因为它不能对新生代进行收集。

快速分配

分配对象的操作需要保证线程安全。

此时分配操作容易成为瓶颈,降低性能。

JVM 采用TLABs(Thread-Local Allocation Buffers)的方式。线程本地分配缓存。

它给每个线程提供自有的缓存—堆的一小部分,线程从中进行分配对象。

这样每个线程分配对象时速度都很快,一旦线程将其TLABs填满后,就需要给它新分配一个,这时就需要同步了。

小于 1%的浪费。不超过10个本地指令。

Serial collector

使用serial 收集器,新生代和老年代收集都是串行的,使用一个CPU,会导致应用暂停。

新生代使用Serial 收集器

1)  将eden中的存活对象进行识别拷贝到 空的 survior区,过大的直接提升

2)  另一个survior中依然存活的对象,够条件的提升,不够的移到另一个survior,如果survior满了,直接提升。

3)  Eden直接释放,eden为空了

收集后的新生代:

对老年代的串行收集

老年代和永久代的收集通过:mark-sweep-compact收集算法。---串行

标记阶段:收集器识别存活对象

清理阶段:将垃圾对象清理掉

压缩阶段:将存活对象拷贝到一端,剩余的一端变成连续的可用空间。

使用条件

Client模式,对暂停时间要求不高。

-XX:+UseSerialGC

并行收集器

吞吐量收集器。可以利用多个CPU。

新生代使用并行收集器

仍然需要暂停应用执行,但是将收集任务分为多个子任务,每个都使用一个CPU执行,降低了执行开销,提升吞吐量。

老年代使用:

Mark-sweep-compact算法。也利用多个CPU。

使用条件

多个CPU,无停顿时间限制

-XX:+UseParallelGC

并行压缩收集器

新的老年代收集算法。

新生代使用:

依然是并行收集。

老年代使用:

三个阶段:

1)  每个分代逻辑划分为多个区

2)  标记阶段:多个线程同时标记出存活对象

3)  存活对象所在区域信息更新,标记出该区域存活对象的位置和大小。

4)  Summary阶段,针对区域操作,左侧区域占用率较高,对这种区域进行压缩,不值得。从左侧开始检查每个区域的空间使用率,直到找到一个区域,其右侧的都值得压缩。此时将待压缩区域的对象情况进行记录。

5)  压缩阶段:垃圾收集器使用多个线程,将summary阶段识别的数据拷贝填充。完毕后右侧会有一个连续较大的内存空间。

使用条件:

使用多个CPU。减少了停顿时间。

-XX:+UseParallelOldGC    -XX:ParallelGCThreads=n

并发标记清理收集(CMS)

响应时间优先。

老年代收集可能带来较长时间的停顿,特别是堆较大时。低延迟收集器。

新生代:使用并行收集

老年代:

初始化标记:短暂的停顿,识别当前直接可达的存活对象

同步标记阶段:标记从初始标记的对象简介可达的所有存活对象,由于系统并发执行,此阶段并不能标记所有的对象

重标记阶段:再次停顿,重新便利并发标记阶段被修改的对象,该阶段停顿时间比初始化标记阶段更长,采用多线程来提高效率。

同步清理阶段:将识别的垃圾对象清理掉。

该算法不会进行压缩。

它使用一个列表保存可用空间地址。造成分配操作复杂耗时。影响新生代的效率。

需要更大的堆空间,因为收集和应用是并发执行的,收集期间会继续分配使用。

收集期间可能一些对象已经变成垃圾数据,这部分清理不掉,只能等到下次收集,被称为floating garbage。

CMS收集器跟踪分配的对象大小,估计后续的需要,有可能将可用空间划分或者集合起来。

CMS不会的等待满了才收集,会稍微提前。一旦老年代满了,CMS会转而是用标记清理压缩算法,为避免这种情况,CMS根据之前收集的次数和耗时的统计数据来自行启动。

CMS也会根据配置的占用率来启动。 -XX:CMSInitiatingOccupancyFraction=n,n代表老年代尺寸的百分比,默认68.

CMS减少老年代的停顿时间,延长了新生代的停顿时间,稍微减少吞吐量,额外的堆。

增量模式

并发阶段增量式进行。

减少长时间并发的影响,转而阶段性停止并发阶段,释放CPU用于执行应用程序。

收集器的工作划分为小的时间段,在新生代收集之间进行。

对于CPU较少但又希望低延迟的应用很有用。

条件

需要更短的停顿,多CPU。

对于长期保留大量存活对象,多余2个CPU的应用有效,例如web server。

-XX:+UseConcMarkSweepGC   -XX:+CMSIncrementalMode

GC

新生代

老年代&永久代

特点

串行

1)  将eden中的存活对象进行识别拷贝到 空的 survior区,过大的直接提升

2)  另一个survior中依然存活的对象,够条件的提升,不够的移到另一个survior,如果survior满了,直接提升。

3)  Eden直接释放,eden为空了

老年代和永久代的收集通过:mark-sweep-compact收集算法。---串行

标记阶段:收集器识别存活对象

清理阶段:将垃圾对象清理掉

压缩阶段:将存活对象拷贝到一端,剩余的一端变成连续的可用空间。

Client模式,对暂停时间要求不高。

-XX:+UseSerialGC

并行

仍然需要暂停应用执行,但是将收集任务分为多个子任务,每个都使用一个CPU执行,降低了执行开销,提升吞吐量。

Mark-sweep-compact算法。

多个CPU,无停顿时间限制

-XX:+UseParallelGC

并行压缩

依然是并行收集。

三个阶段:

1)  每个分代逻辑划分为多个区

2)  标记阶段:多个线程同时标记出存活对象

3)  存活对象所在区域信息更新,标记出该区域存活对象的位置和大小。

4)  Summary阶段,针对区域操作,左侧区域占用率较高,对这种区域进行压缩,不值得。从左侧开始检查每个区域的空间使用率,直到找到一个区域,其右侧的都值得压缩。此时将待压缩区域的对象情况进行记录。

5)  压缩阶段:垃圾收集器使用多个线程,将summary阶段识别的数据拷贝填充。完毕后右侧会有一个连续较大的内存空间。

使用多个CPU。减少了停顿时间。

-XX:+UseParallelOldGC    -XX:ParallelGCThreads=n

CMS

使用并行收集

CMS不能对新生代收集

初始化标记:短暂的停顿,识别当前直接可达的存活对象

同步标记阶段:标记从初始标记的对象简介可达的所有存活对象,由于系统并发执行,此阶段并不能标记所有的对象

重标记阶段:再次停顿,重新便利并发标记阶段被修改的对象,该阶段停顿时间比初始化标记阶段更长,采用多线程来提高效率。

同步清理阶段:将识别的垃圾对象清理掉。

该算法不会进行压缩。

它使用一个列表保存可用空间地址。造成分配操作复杂耗时。影响新生代的效率。

需要更大的堆空间,因为收集和应用是并发执行的,收集期间会继续分配使用。

收集期间可能一些对象已经变成垃圾数据,这部分清理不掉,只能等到下次收集,被称为floating garbage。

CMS收集器跟踪分配的对象大小,估计后续的需要,有可能将可用空间划分或者集合起来。

CMS不会的等待满了才收集,会稍微提前。一旦老年代满了,CMS会转而是用标记清理压缩算法,为避免这种情况,CMS根据之前收集的次数和耗时的统计数据来自行启动。

CMS也会根据配置的占用率来启动。 -XX:CMSInitiatingOccupancyFraction=n,n代表老年代尺寸的百分比,默认68.

CMS减少老年代的停顿时间,延长了新生代的停顿时间,稍微减少吞吐量,额外的堆

CMS增量模式

并发阶段增量式进行。

减少长时间并发的影响,转而阶段性停止并发阶段,释放CPU用于执行应用程序。

收集器的工作划分为小的时间段,在新生代收集之间进行。

对于CPU较少但又希望低延迟的应用很有用。

自动选择及行为优化

5.0后,JVM会根据应用所在的系统自动选择收集器、堆、jvm模式。

自动选择垃圾收集器、堆大小、JVM模式

Server-class机器环境:

至少2个物理处理器

至少2G物理内存

除了32位的windows操作系统,其他平台都使用上述定义。

对于非server-class机器,默认参数:

1)      Client JVM

2)      串行垃圾收集

3)      初始堆4M

4)      最大堆64M

Server-class机器上,server模式时默认为并行收集器。

Server-class机器上JVM使用并行收集器时默认参数为:

1)  初始堆,物理内存 1/64,最大1G。

2)  最大堆: 1/4物理内存,最大1G。

基于行为的并行收集器调优

最大停顿时间目标: -XX:MaxGCPauseMillis=n

该参数提示并行收集器停顿时间不要超过 n 毫秒。收集器会调整堆大小和其他相关参数去尽力达到停顿时间目标。但这些调整由可能降低系统吞吐量。

吞吐量目标

吞吐量:gc时间和非gc时间。

-XX:GCTimeRatio=n

Gc时间为: 1/(1+n)

占用量目标

吞吐量和停顿时间都达到后,gc会减少堆直到其中一个目标不满足(一直都会是 吞吐量目标),不满足目标后,gc再调整来满足该目标。

-========那岂不是一直在抖动?????

目标的优先级

并行收集器,会首先去满足最大停顿时间目标。然后是吞吐量,占用量目标只会在前两个都满足后才会去考虑。

其他建议

首先建议系统默认选择,然后测试是否符合要求。

如果gc出现性能问题,首先考虑收集器是否和对应操作系统符合,尝试切换收集器。

可以通过工具来分析性能问题,根据分析结果考虑修改步骤。

–XX:+UseSerialGC

–XX:+UseParallelGC

–XX:+UseParallelOldGC

–XX:+UseConcMarkSweepGC

堆大小调整

1、  有足够大的内存

2、  堆不同分代的划分,串行收集时新生代不要超过一半。

并行收集调优策略

OutOfMemoryError

Gc找不到足够内存来分配对象,堆也不能再扩展了。

不一定是内存泄露了。

首先检查错误信息。

Java heap space.表明堆中没法分配空间了。调整堆大小。

PermGen space。永久区满了。调整永久区大小。

Requested array size exceeds vm limit。数组超限。

可使用HAT来分析。

评估GC性能的工具

-XX:+PrintGCDetails 会打印gc前后的各个分代存活对象信息,可用空间,GC耗时。

-XX:+PrintGCTimeStamps gc启动的时间戳。

Jmap/jstat/HPROF/HAT

GC的关键参数

【笔记】memorymanagement-whitepaper-150215的更多相关文章

  1. git-简单流程(学习笔记)

    这是阅读廖雪峰的官方网站的笔记,用于自己以后回看 1.进入项目文件夹 初始化一个Git仓库,使用git init命令. 添加文件到Git仓库,分两步: 第一步,使用命令git add <file ...

  2. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  3. SQL Server技术内幕笔记合集

    SQL Server技术内幕笔记合集 发这一篇文章主要是方便大家找到我的笔记入口,方便大家o(∩_∩)o Microsoft SQL Server 6.5 技术内幕 笔记http://www.cnbl ...

  4. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  5. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  6. NET Core-学习笔记(三)

    这里将要和大家分享的是学习总结第三篇:首先感慨一下这周跟随netcore官网学习是遇到的一些问题: a.官网的英文版教程使用的部分nuget包和我当时安装的最新包版本不一致,所以没法按照教材上给出的列 ...

  7. springMVC学习笔记--知识点总结1

    以下是学习springmvc框架时的笔记整理: 结果跳转方式 1.设置ModelAndView,根据view的名称,和视图渲染器跳转到指定的页面. 比如jsp的视图渲染器是如下配置的: <!-- ...

  8. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  9. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  10. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

随机推荐

  1. HMC破解控制台密码

    一般我们装完HMC以后默认的登录控制台的账户是:admin 密码:abc123当我们可以自创建登录账户后,忘记密码了怎么办? 这里有两种方法: 1 由于HMC是suse系统,基于linux内核的,所以 ...

  2. web初学之重定向与请求转发

    重定向与请求转发的问题 (1)RequestDispatcher是通过调用HttpServletRequest对象的getRequestDispatcher()方法得到的,是属于请求对象的方法. (2 ...

  3. 对 clear:both 这个样式的一些理解

    看下我今天一直研究的两个例子吧.希望对自己跟大家有帮助: 例子一: <!DOCTYPE html> <html> <head lang="en"> ...

  4. windows server 无人值守安装

    使用 answer file:AutoUnattend.xml 来无人值守安装,到了选系统这步 还是要手动选择一个系统,这是为什么?怎么设置可以默认进入GUI的系统进行安装啊?

  5. C6000代码层面优化(一)

    2014年8月7日,看了一片很长见识的博文,关于DSP如何优化的,有一个问题没有搞通,“百度”一下关键字,居然搜查了一模一样的博文N片,现在也搞不懂这篇博文的原创作者是谁了.反正我感觉直接转摘过去,要 ...

  6. The CLR's Thread Pool

    We were unable to locate this content in zh-cn. Here is the same content in en-us. .NET The CLR's Th ...

  7. 【POJ2699】The Maximum Number of Strong Kings(二分,最大流)

    题意: 有n个队伍,两两都有比赛 知道最后每支队伍获胜的场数 求最多有多少队伍,他们战胜了所有获胜场数比自己多的队伍,这些队伍被称为SK N<=50 思路:把每个队伍和它们两两之间的比赛都当做点 ...

  8. (转)tar.xz文件如何解压

    XZ压缩最新压缩率之王 xz这个压缩可能很多都很陌生,不过您可知道xz是绝大数Linux默认就带的一个压缩工具. 之前xz使用一直很少,所以几乎没有什么提起. 我是在下载phpmyadmin的时候看到 ...

  9. JQM---列车时刻查询

    <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8& ...

  10. Number Sequence HDU 1711(KMP)

    http://acm.hdu.edu.cn/showproblem.php?pid=1711 首次接触KMP,自己都不是特别理解.在网上百度看了好几个帖子之后,对KMP也有了初步的理解. #inclu ...