在大型的java运用中,要进行程序调优,指定一个合
适的垃圾回收机制是必不可少的,那如何可确定某gc是否使得程序最优化呢?我们可以查看jvm打印出
的gc日志来分析,并做出进一步优化,而目前并没有一篇文章明确的指明java中各种gc算法打印出日志的格式,以及如何阅读。所以接下来本文将试着边介
绍各种垃圾回收机制边解释该回收机制下log的格式。
1,垃圾收集算法
1.1 引用计数法(Reference Counting Collector)
系统记 录对象被应用的次数,当应用次数为0时,就可以将该对象所占内存回收。该算法可以不用暂停运用,但缺点是无法解决重复运用的问题。所以java并没有提供 此类垃圾回收器。
1.2
tracing算法(Tracing Collector)
tracing算法的垃圾收集器从根集开始扫描,识别出哪些对象可达,哪 些对象不可达,并用某种方式标记可达对象。
1.2.1 复制 ( Copying )算法
复制算法将堆等分成2个区域,一个区域含有现在的数据对象(ToSpace),而另一个区域包含
废
弃的数据(FromSpace)。复制算法将存活的对象从FromSpace复制到ToSpace,然后切换Fromspace和ToSpace的指针,
以前的FromSpace变为现在的ToSpace区域。
1.2.2 标记-整理( Mark-Compact )算法
1.2.3 标记-清除(Mark-Sweep)
Using the -XX flags for our collectors for jdk6,
-
UseSerialGC is "Serial" + "Serial Old"
-
UseParNewGC is "ParNew" + "Serial Old"
-
UseConcMarkSweepGC
is "ParNew" + "CMS" + "Serial Old". "CMS" is used most of the time to
collect the tenured generation. "Serial Old" is used when a concurrent
mode failure
occurs.
-
UseParallelGC is "Parallel Scavenge" + "Serial Old"
-
UseParallelOldGC is "Parallel Scavenge" + "Parallel Old"
SerailGC
1,Serial Young GC
0.246: [GC 0.246: [DefNew: 1403K->105K(1984K), 0.0109275 secs] 1403K->1277K(6080K), 0.0110143 secs]
2, Serial Olg Gc
1.133: [GC 1.133:
[DefNew: 960K->64K(960K), 0.0012208 secs]1.135: [Tenured:
7334K->7142K(7424K), 0.0213756 secs] 7884K->7142K(8384K), [Perm :
364K->364K(12288K)], 0.0226997 secs] [Times: user=0.01 sys=0.00,
real=0.02 secs]
Parrallel GC
serailGC的适应muti Core的加强版,就是在minorGC时候采用并行的进行收集,而fullGC并没有改变
Parralllel Compacting GC
在parrallelGC的基础上将fullgc也变为并发的了
With the parallel compacting
collector, the old and permanent generations are collected in a
stop-theworld,mostly parallel fashion with sliding compaction. The
collector utilizes three phases. First, each generation
is logically divided into fixed-sized regions. In the marking phase,
the initial set of live objects directly reachable from the application
code is divided among garbage collection threads, and then all live
objects are marked in parallel. As an object is
identified as live, the data for the region it is in is updated with
information about the size and location of the object.备注 待翻译
Concurrent Mark-Sweep (CMS) Collector
有一种需求是应用的相应时间比应用的吞吐重要,为了满足这种需求,jvm提供了该场景下的垃圾收集器CMS,使用该垃圾收集器的时候minorGC和 ParralelGC当中采用的一样,只是在老生代更换了不同的算法。
CMS将老生代的回收分为4个阶段 其中只有2个阶段是要stop-the-world的,而其余阶段是不需要的,因此降低了系统暂停时间,缺点是在其余的2个阶段会更应用抢jvm资源。
从上图可以看出,CMS的运 行过程。
A collection cycle for the CMS collector starts with a short pause, called the initial mark, that
identifies the initial set of live objects directly reachable from the application code. Then,
during the concurrent marking phase, the collector marks all live objects that are transitively
reachable from this set.
Because the application is running and updating reference fields while
the marking phase is taking place, not all live objects are guaranteed
to be marked at the end of the concurrent marking
phase. To handle this, the application stops again for a second pause,
called remark, which finalizes marking by revisiting any objects that
were modified during the concurrent marking phase. Because the remark
pause is more substantial than the initial mark,
multiple threads are run in parallel to increase its efficiency.
备注 待翻译
Concurrent Mark-Sweep GC log format:
Full GC 被调用的出现情况
promotion failed(
mark-sweep-compact stop-the-world
)
ParNew
(promotion failed): 当老生代空闲空间存在碎片,导致没有足够大的连续空间开存放新生代对象的升级时,机会触发promotion failed。
此时调用一个Mark-Compact 垃圾收集器是很有必要的。(默认采用 Serial Old GC)
106.641: [GC 106.641: [ParNew (promotion failed): 14784K->14784K(14784K), 0.0370328 secs]106.678:
[CMS106.715:
[CMS-concurrent-mark: 0.065/0.103 secs] [Times: user=0.17 sys=0.00, real=0.11 secs]
(concurrent
mode failure): 41568K->27787K(49152K), 0.2128504 secs]
52402K->27787K(63936K), [CMS Perm : 2086K->2086K(12288K)],
0.2499776 secs] [Times:
user=0.28 sys=0.00, real=0.25 secs]
full promotion guarantee failure
(
concurrent mode failure
):
当垃圾回收算法预测在下一次Conc-Mark-Sweep算法调用之前,老生代的空余空间将会被系统占用光。为了解决这一问题,垃
圾回收算法进入conccurent mode failure状态,调用一个 stop-the-world(serail Old GC)来清理系统Heap。
eg:为了触发这种情况 我们先分配64m内存给jvm,然后新生代和老年代的占用比例为7,即老年代用了7*8=58 触 发concurrent mode failure的情况:
public class FullPromotionGuaranteeFailure
{
public static void main(String[] args)
{
List<byte[]> bytesList = new ArrayList<byte[]>();
for (int i = 0; i < 7 * 8 * 1024; i++)
{
bytesList.add(new byte[1024]);
}
//bytesList = null; 没有必要的 gc会知道函数里面变量是否还会被引用
byte[] bytes = new byte[16 * 1024 * 1024];
String.valueOf(bytes[0]);
}
}
运 行时JVM参数:
-Xmx64m -Xms64m -XX:NewRatio=7 -XX:MaxTenuringThreshold=0 -verbose:gc
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps
-XX:+PrintGCApplicationStoppedTime -XX:+UseConcMarkSweepGC
-Xloggc:full-promotion-guarantee-failure.log
full-promotion-guarantee-failure.log 内容
0.195: [GC 0.195:
[ParNew: 2986K->2986K(8128K), 0.0000083 secs]0.195: [CMS0.212:
[CMS-concurrent-preclean: 0.011/0.031 secs] [Times: user=0.03 sys=0.02,
real=0.03 secs]
(concurrent mode failure): 56046K->138K(57344K), 0.0271519 secs]
59032K->138K(65472K), [CMS Perm : 2079K->2078K(12288K)], 0.0273119
secs] [Times: user=0.03 sys=0.00, real=0.03 secs]
调用Serial Old GC 是费时并且暂停了整个应用,这显然不是我们想看到的。为了 避 免办法出现(
concurrent mode failure
)这种情况,可以参考bluedavy的该篇blog
GC
策略的调优
Stop-the-world GC happens when a JNI critical section is released
. Here again the young generation collection failed due to "full promotion guarantee failure" and then the Full GC was invoked.
283.736: [Full GC 283.736: [ParNew: 261599K->261599K(261952K), 0.0000615 secs]
826554K->826554K(1048384K), 0.0003259 secs]
GC locker: Trying a full collection because scavenge failed
分享到:
相关推荐
通过在java命令种加入参数来指定对应的gc类型,打印gc日志信息并输出至文件等策略。 在Java虚拟机中,GC日志分析可以通过以下命令实现: * -XX:+PrintGC 输出GC日志 * -XX:+PrintGCDetails 输出GC的详细日志 * -XX...
通过分析这些GC日志,我们可以了解JVM内存的使用情况、垃圾收集的频率和效率,以及可能的性能瓶颈。例如,频繁的Full GC可能会导致应用性能下降,需要检查是否需要调整内存分配策略或选择更适合的垃圾收集器。同时,...
本文将详细介绍如何通过Java的GC日志以及GCViewer工具来分析和优化垃圾回收。 首先,我们需要了解什么是GC日志。在Java中,通过设置JVM参数,我们可以开启GC日志功能,记录每一次垃圾回收的详细信息。例如,我们...
在Android系统中,GC2145 MIPI驱动可能包含一个内核模块,用于处理硬件初始化、数据传输等低级操作,以及一个HAL(Hardware Abstraction Layer)层,作为用户空间与内核空间交互的接口。 在Android 4.4系统中,GC...
配置MQ日志时,你可以指定日志文件的数量、大小以及日志策略,比如循环日志、归档日志等。这通常在队列管理器的配置文件`qm.ini`中进行设置。了解和掌握MQ日志的相关知识对于管理和维护MQ环境至关重要,特别是在处理...
在进行 LoadRunner 结果分析时,通常需要结合日志文件、监控数据以及各种诊断工具,比如 jconsole、jvisualvm 等,进行综合判断。同时,理解应用程序的业务逻辑和架构也是至关重要的,以便定位问题并提出有效的解决...
- **GC类型**:主要分为Minor GC(年轻代GC)、Major GC(老年代GC)和Full GC(全局GC)。 - **GC策略**:包括复制算法、标记-清除算法、标记-整理算法、分代收集策略等,根据JVM版本和配置不同而有所不同。 - *...
它包括设定诊断项目、开始诊断、停止或退出诊断,以及读取日志菜单中的GC操作日志、分析日志、参数日志、错误日志和诊断日志,这些日志有助于快速定位仪器故障并进行相应的维护。 分析计数器和冷媒消耗计数器: ...
为了更好地理解和监控GC的行为,可以通过日志文件来跟踪GC的运行情况。例如,下面是一个简单的GC日志输出示例: ``` [GC (Allocation Failure) [PSYoungGen: 1168K->480K(1536K)] 1168K->1064K(3752K), 0.0012940 ...
然后,将生成的GC日志文件导入到gchisto.jar,它会自动生成对应的分析报告。 此外,由于gchisto.jar的标签涉及到“多线程”,我们可以推断该工具可能还具备处理多线程环境下GC日志的能力。在多线程环境中,内存管理...
- **日志类型**:包括tomcat catalina、gc、access log等。 - **日志管理**:通过`rsyslog`或`filebeat`等工具进行管理。 - **Kubernetes容器日志**: - **非标准日志与标准日志**:Kubernetes支持两种类型的日志...
《JDK12 GC调优秘籍》是针对Java开发人员的一份重要参考资料,它以PDF的形式详尽列出了JDK12中的垃圾收集(GC)相关参数,旨在帮助开发者优化应用程序性能。以下是对这份秘籍中部分重要参数的详细说明: **JIT...
4. **GC日志分析**:通过`-XX:+PrintGCDetails`和`-XX:+PrintGCDateStamps`等参数,记录GC信息,以便分析GC行为和性能瓶颈。 JVM调优则更广泛,除了GC之外,还包括: 1. **类加载机制**:理解双亲委派模型,以及...
5. **GC日志分析**:启用JVM的垃圾收集日志,通过分析GC行为来判断是否存在内存管理问题。 四、优化策略 1. **内存泄漏检测**:使用专业工具检测内存泄漏,及时释放不再使用的对象。 2. **对象池技术**:对频繁...
本次我们将深入探讨的是一款名为WoWTCGUtility的iOS应用源码,该源码来自于乔布斯的个人项目,版本号为0.81,基于桌面平台,Git提交ID为gc84076b。通过分析这个项目,我们可以了解iOS应用的基本架构、常用编程技巧...
Java性能调优涉及代码层面优化、JVM参数调优以及垃圾收集器(GC)调优等多个方面。 ### 代码调优 代码层面的优化通常遵循“简单即正义”的原则,要求开发者优化代码逻辑,减少不必要的计算,避免无用代码的生成,...
面试中,面试官可能会询问你关于GC的工作原理,比如不同类型的垃圾收集器,如何调优GC参数,以及如何处理内存泄漏和长时间的垃圾收集暂停。 4. **多线程编程**(对应Day3 - Thread.txt): 多线程是并发执行任务的...
生成GC日志的参数包括"XX:+PrintGC"用于输出简要GC日志,"XX:+PrintGCDetails"用于输出详细GC日志,以及"Xloggc:gc.log"用于指定GC日志文件的输出路径。需要注意的是,"Xmn"参数在JDK1.4版本之后才被使用,它同时...
10. **错误处理与日志记录**:在进行数据库操作时,错误处理和日志记录是重要的实践,以确保测试的可追溯性和问题排查。 了解以上知识点后,你可以根据项目需求安装并使用这个"Database Library",通过Robot ...