通常,在调优Java程序时,重点放在两个主要目标之一:响应性或吞吐量。
响应性响应性是指应用程序或系统响应所请求的数据的速度。
比如:
桌面UI 对一个event事件响应有多快。一个网站返回一个页面的速度有多快返回数据库查询的速度有多快
对于注重响应的应用程序,长时间的暂停是不可接受的。重点是在短时间内做出反应。
吞吐量吞吐量主要关注应用程序在特定时间内工作量的最大化。比如下面测量吞吐量的例子:
在给定的时间内完成的事务数批处理程序在一个小时内完成的作业数一个小时内完成的数据库查询数量
对于注重吞吐量的应用程序来说,高暂停时间是可以接受的。因为高吞吐量的应用程序关注一段时间内吞吐量基准测试,快速响应时间不是一个考虑因素。
G1垃圾收集器Garbage-First(G1)收集器是一款针对服务器端的垃圾收集器,针对具有大内存的多处理器机器。它以较高的概率满足垃圾收集(GC)暂停时间目标,同时实现了高吞吐量。G1垃圾收集器在Oracle JDK 7更新4及以后的版本中得到了完全支持。G1收集器设计用于以下应用:
可以与应用程序线程并发 *** 作,比如CMS收集器压缩可分配空间,不需要长时间的GC导致的暂停时间需要更多的可预测的GC暂停时间不想要牺牲大量的吞吐量性能不需要更大的Java堆
G1 作为并发标记-清除处理器的长期替代品。与CMS相比,G1有一些不同之处使得G1成为更好的解决方案。一个区别就是G1是一个压缩型收集器。G1充分压缩完全避免细粒度的空闲列表来分配,而是依赖区域(Region)。这大大简化了收集器的部分工作,并在很大成都上消除了潜在的碎片问题。此外,G1提供了比CMS收集器更可预测的垃圾收集暂停,并允许用户指定所需的暂停目标。(One difference is that G1 is a compacting collector. G1 compacts sufficiently to completely avoid the use of fine-grained free lists for allocation, and instead relies on regions. This considerably simplifies parts of the collector, and mostly eliminates potential fragmentation issues. Also, G1 offers more predictable garbage collection pauses than the CMS collector, and allows users to specify desired pause targets.)
G1 *** 作概述较老的垃圾收集器(并行、串行、CMS)将堆结构分为三个部分:年轻代、年老代和固定内存大小的永久代。
(永久代 jdk1.8之后就变成metaSpace 了)
所有内存对象最终都在这三个部分中的一个区域里。
G1收集器采用了不同的方法:
整块堆被划分为一组大小相等的小块堆区域,每一个都是连续的虚拟内存。某些区域被设置充当与较老收集器相同的角色(Eden、survivor、old),但它们没有固定的大小。这在内存使用方面提供了更大的灵活性。
当执行垃圾收集时,G1的 *** 作在某种个方面类似于CMS收集器。G1会执行一个并发的全局标记阶段来确定整个堆中活着的的对象。在标记阶段完成后,G1就会知道哪些区域大部分是空的。它首先在这些区域收集,这通常会产生大量的空闲空间。这就是为什么这种垃圾收集方法被称为Garbage-First.顾名思义,G1将其收集和压缩活动集中在堆中可能充满可回收对象(垃圾)的区域。G1使用暂停预测模型来满足用户自定义的暂停时间目标。
被G1认定为成熟可回收的区域通过疏散(evacuation)被垃圾回收。G1将对象从堆中的一个或多个区域复制到堆中的单个区域,在这个过程中压缩和释放内存。这种疏散在多处理器上并行执行,以减少暂停时间并提高吞吐量。因此,随着每次的垃圾收集,G1不断的工作以减少碎片,在用户定义的暂停时间内工作。这超出了之前两种垃圾回收方法的能力。CMS(并发标记清除)垃圾收集器不做压缩。ParallelOld 垃圾收集只执行整个堆压缩,这会导致相当长的暂停时间。
值得注意的是G1不是一个实时收集器。它以较高的概率满足设定的暂停时间目标,但不是绝对确定的。基于之前回收的数据,G1会估计在用户指定的目标时间内可以收集多少个区域。因此收集器对收集区域的成本有一个相当准确的模型,并且它使用这个模型来确定在保持暂停时间目标的情况下收集哪些和多少个区域。
注意:G1有并发(与应用程序线程一起运行,例如细化、标记、清理)和并行(多线程,例如,停止世界)两个阶段。完整的垃圾收集(Full GC)仍然是单线程的,但是如果调整得当,应用程序应该避免完整的GC。
G1推荐用例G1 的首先关注的是为运行需要大堆且GC延迟有限的应用程序的用户提供解决方案。
这意味着堆大小约为6GB或者更大并且稳定且可预测的暂停时间低于0.5秒。
今天运行CMS或ParallelOldGC垃圾收集器的应用程序,如果具有以下一个或多个特征,则切换到G1将受益。
Full GC持续时间太长或太频繁对象的分配率或者提升率差异很大不满足于长时间的垃圾收集或者压缩暂停时间(超过0.5到1秒)
注意:如果您正在使用CMS或者ParallelOldGC,并且您的应用程序没有遇到过长时间的垃圾收集暂停,那么可以使用当前的收集器。使用最新的JDK并不需要更改到G1收集器。
回顾分代GC和CMS并发标记清除(CMS)收集器(也称为并发低暂停收集器)收集老年代。它试图通过与应用程序线程并发执行大部分垃圾收集工作来最小化垃圾收集导致的暂停时间。
通常,并发低暂停收集器不会复制或压缩存活对象。垃圾收集在不移动存活对象的情况下完成。如果内存碎片成为问题,则分配更大的堆。
CMS收集器在年轻代上使用与并行收集器相同的算法。
CMS收集阶段CMS收集器在堆的老年代上执行以下阶段:
接下来,让我们一步一步地回顾CMS收集器的 *** 作。
1.CMS收集器的堆结构
堆被分成三个区域。
年轻代被分成Eden区和两个survivor区,而老年代是一块连续的区域。除非发生Full GC,否则不会进行压缩。
2.Young GC 在CMS下是如何工作的
年轻代对象用浅绿色标记,年老代用蓝色标记。如果您的应用程序已经运行了一段时间,那么这就是CMS的样子。对象分散在老年代区域。
使用CMS,老年代对象在适当的位置(什么是适当的位置我也不太清除我觉着就是分配的位置)被回收。它们不会移动。除非发生Full GC,否则空间不会被压缩。
3.年轻代集合
存活的对象从Eden区和一个survivor区复制到另一个survivor区。任何已经达到老化阈值的较老对象被提升到老年代。
4.Young GC 之后
在一次Young GC之后,Eden空间被清理,其中一个Survivor空间被清理。
新晋升的对象在图表中以深蓝色显示。绿色对象是尚存活的年轻代对象,还没有提升到老年代。
5.CMS老年代收集
两个STW事件会发生:初始标记和再次标记。当老年代达到一定的占用率的时候,CMS就启动了。
(1)初始标记是一个短暂的暂停阶段。在此阶段 标记存活(可达)对象。(2)并发标记在应用程序继续执行时查找存活对象。最后,在(3)再次标记阶段,发现(2)并行标记前一阶段中遗漏的对象。
6.老年代收集-并发清除
在前一阶段中未被标记的对象的位置将被重新分配,这时并没还有压缩空间。
Note: Unmarked objects == Dead Objects
7. 老年代收集-清除之后
在(4)sweep 阶段之后,你可以看到大量内存被释放。你还可以注意到没有进行压缩。
最后,CMS收集器将进入(5)重置阶段,并等待下一次达到GC阈值。
G1垃圾收集器G1收集器采用不同的方法分配堆。下面的图片一步一步地回顾一下G1系统。
1. G1堆结构
G1 下的堆是一个被分割成许多固定大小的区域(region)的内存区域(area)。
region大小由JVM启动时选择。JVM通常以大约2000个大小从1到32MB范围的区域为分割目标。
2.G1 堆分配
实际上,这些区域被映射成Eden、survivor和Old空间的逻辑代表。
图中的颜色显示了哪个region与哪个角色相关联。存活对象被从一个区域疏散(即复制或移动)到另一个区域。
Regions被设计成并行收集或者不停止所有其他应用线程。(Regions are designed to be collected in parallel with or without stopping all other application threads.)-翻译in parallel with or without
如上所示 ,区域可以分配为Eden区、survivor区和generation区域。此外,还有第四种被称为Humongous 区域。这些区域用于保存大小为标准区域的50%或更大的对象。它们被保存在一组相邻的区域中。最后一种区域是堆中未被使用的区域。
注意:在撰写本文时,还没有对收集大型对象进行优化。因此,应该避免创建这种大小的对象。
3.G1年轻代
堆被分成大约2000个区域。最小的大小为1Mb,最大的为32Mb。蓝色区域持有老年代对象,绿色区域持有年轻代对象。
注意:这些区域不需要像旧的垃圾收集器那样是连续的(两个young region 之间不一定连续,可能隔着Old region)。
4.G1年轻代GC
存活对象被疏散(即复制或移动)到一个或多个survivor区域。当满足老化阈值时,部分对象将被提升到Old generation region。
这是一个停止世界的暂停。为了下一次GC Eden大小和survivor大小被计算。在计算大小的时候,像pause time goal 这样的事情也要考虑在内。
这种方法使得调整region大小变得非常容易,可以根据需要放大或缩小区域。
5.一次G1 Young GC 之后
存活对象被疏散到Survivor 区或者 Old 区。
最近晋升对象用深蓝色显示,Survivor Regions in Green.
综上所述,G1的年轻代可以总结为下面说的:
堆是一块被分割成多个区域的内存空间年轻代内存由一组非连续区域组成。这使得在需要时可以容易的调整年轻代大小。年轻代的垃圾收集,或年轻的GC,是停止世界事件(STW)。所有应用程序都将为此 *** 作而停止。Young GC 是使用多线程并行完成的。存活对象是被赋值到新的Survivor区或者Old区 的。 G1的年老代GC
与CMS收集器一样,G1收集器被设计为老年代低暂停收集器。下面描述了老年代G1收集阶段。
G1收集阶段-并发标记周期阶段G1收集器在堆的老年代上执行以下阶段。注意,有些阶段是年轻代收集的一部分。
(Stop the World Event)This is a stop the world event. With G1, it is piggybacked on a normal young GC. Mark survivor regions (root regions) which may have references to objects in old generation.
(Stop the World Event)Completes the marking of live object in the heap. Uses an algorithm called snapshot-at-the-beginning (SATB) which is much faster than what was used in the CMS collector.
(Stop the World Event and Concurrent)
Performs accounting on live objects and completely free regions. (Stop the world)Scrubs the Remembered Sets. (Stop the world)Reset the empty regions and return them to the free list. (Concurrent)
(Stop the World Event)These are the stop the world pauses to evacuate or copy live objects to new unused regions. This can be done with young generation regions which are logged as [GC pause (young)]. Or both young and old generation regions which are logged as [GC Pause (mixed)].
With the phases defined, let's look at how they interact with the old generation in the G1 collector.
6.Initial Marking Phase
Initial marking of live object is piggybacked on a young generation garbage collection. In the logs this is noted as GC pause (young)(inital-mark).
7.Concurrent Marking Phase
If empty regions are found (as denoted by the "X"), they are removed immediately in the Remark phase. Also, "accounting" information that determines liveness is calculated.
8.Remark Phase
Empty regions are removed and reclaimed. Region liveness is now calculated for all regions.
9. Copying/Cleanup Phase
G1 selects the regions with the lowest "liveness", those regions which can be collected the fastest. Then those regions are collected at the same time as a young GC. This is denoted in the logs as [GC pause (mixed)]. So both young and old generations are collected at the same time.
10. After Copying/Cleanup Phase
The regions selected have been collected and compacted into the dark blue region and the dark green region shown in the diagram.
Summary of Old Generation GCIn summary, there are a few key points we can make about the G1 garbage collection on the old generation.
Concurrent Marking Phase
Liveness information is calculated concurrently while the application is running.This liveness information identifies which regions will be best to reclaim during an evacuation pause.There is no sweeping phase like in CMS.Remark Phase
Uses the Snapshot-at-the-Beginning (SATB) algorithm which is much faster then what was used with CMS.Completely empty regions are reclaimed.Copying/Cleanup Phase
Young generation and old generation are reclaimed at the same time.Old generation regions are selected based on their liveness.
翻译原文:
Getting Started with the G1 Garbage Collectorhttps://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)