Java垃圾收集日志消息

Eth*_*man 94 java logging garbage-collection

我已经将java配置为将垃圾收集信息转储到日志中(详细GC).我不确定日志中的垃圾收集条目是什么意思.这些条目的样本发布在下面.我在Google上搜索过,并没有找到可靠的解释.

我有一些合理的猜测,但我正在寻找答案,这些答案提供了条目中数字的严格定义,并由可靠的消息来源支持.对所有引用sun文档的答案自动+1.我的问题是:

  1. PSYoungGen是指什么?我认为它与之前的(年轻?)一代有关,但具体到底是什么?
  2. 第二个三元组和第一个三元组有什么区别?
  3. 为什么名称(PSYoungGen)指定为第一个三元组而不是第二个?
  4. 三元组中的每个数字(内存大小)是什么意思.例如,在109884K-> 14201K(139904K)中,是GC 109884k之前的存储器,然后它减少到14201K.第三个数字如何相关?为什么我们需要第二组数字?

8109.128:[GC [PSYoungGen:109884K-> 14201K(139904K)] 691015K-> 595332K(1119040K),0.0454530秒]

8112.111:[GC [PSYoungGen:126649K-> 15528K(142336K)] 707780K-> 605892K(1121472K),0.0934560 secs]

8112.802:[GC [PSYoungGen:130344K-> 3732K(118592K)] 720708K-> 607895K(1097728K),0.0682690 secs]

mic*_*eph 127

  1. PSYoungGen指的是用于次要集合的垃圾收集器.PS代表Parallel Scavenge.
  2. 第一组数字是年轻一代的前/后大小,第二组是整个堆.(诊断垃圾收集问题详细说明格式)
  3. 名称表示有问题的生成和收集器,第二组用于整个堆.

相关完整GC的示例还显示了用于旧代和永久代的收集器:

3.757: [Full GC [PSYoungGen: 2672K->0K(35584K)] 
            [ParOldGen: 3225K->5735K(43712K)] 5898K->5735K(79296K) 
            [PSPermGen: 13533K->13516K(27584K)], 0.0860402 secs]
Run Code Online (Sandbox Code Playgroud)

最后,分解示例日志输出的一行:

8109.128: [GC [PSYoungGen: 109884K->14201K(139904K)] 691015K->595332K(1119040K), 0.0454530 secs]
Run Code Online (Sandbox Code Playgroud)
  • GC之前使用107Mb,GC 之后使用14Mb,最大年轻一代137Mb
  • GC之前使用675Mb堆,GC 之后使用581Mb堆,最大堆大小为1Gb
  • 自从JVM启动以来,次要GC发生了 8109.128秒,耗时0.04

  • 只是一个小评论,'()'之间的值不是最大尺寸,永远是当前的最大尺寸.如果GC无法释放堆少于此限制,则操作系统将需要更多空间,并且此值将增加.当然要遵守以下定义的限制:-Xmx (8认同)

Mic*_*ers 90

其中大部分内容都在GC调整指南中进行了解释(无论如何你都可以阅读).

命令行选项-verbose:gc会在每个集合中打印有关堆和垃圾回收的信息.例如,这是从大型服务器应用程序输出:

[GC 325407K->83000K(776768K), 0.2300771 secs]
[GC 325816K->83372K(776768K), 0.2454258 secs]
[Full GC 267628K->83769K(776768K), 1.8479984 secs]
Run Code Online (Sandbox Code Playgroud)

在这里,我们看到两个小集合,后面是一个主要集合.箭头之前和之后的数字(例如,325407K->83000K来自第一行)分别指示垃圾收集之前和之后的活动对象的组合大小.在次要集合之后,大小包括一些垃圾(不再存活)但无法回收的对象.这些对象或者包含在终身代中,或者从终身代或永久代引用.

括号中的下一个数字(例如,(776768K)再次来自第一行)是堆的已提交大小:可用于Java对象的空间量,而无需从操作系统请求更多内存.请注意,此数字不包括幸存者空间之一,因为在任何给定时间只能使用一个,并且不包括永久生成,其中包含虚拟机使用的元数据.

该行的最后一项(例如0.2300771 secs)表示执行收集所需的时间; 在这种情况下大约四分之一秒.

第三行中主要集合的格式类似.

产生的输出格式-verbose:gc在未来版本中可能会有所变化.

我不确定为什么你的PSYoungGen会出现; 你改变了垃圾收集器吗?

  • 这个答案并没有真正解决原始问题.我觉得michaeljoseph的答案更好.它解决了Ethan提出的问题,并且更好地打破了原始示例.虽然他的答案有两个问题(他的链接已经死了,而rafa.ferreria已经指出了另一个),但它并不只是反刍Oracle文档. (7认同)

And*_*rei 23

我只是想提一下,可以用.获取详细的GC日志

-XX:+PrintGCDetails 
Run Code Online (Sandbox Code Playgroud)

参数.然后你会在答案中看到PSYoungGen或PSPermGen输出.

-Xloggc:gc.log似乎产生像相同的输出-verbose:gc,但是你可以指定在第一个输出文件.

用法示例:

java -Xloggc:./memory.log -XX:+PrintGCDetails Memory
Run Code Online (Sandbox Code Playgroud)

为了更好地可视化数据,您可以尝试gcviewer(可以在github上找到更新的版本).

注意正确编写参数,我忘记了"+",我的JBoss无法启动,没有任何错误信息!

  • 请注意,当重新启动java时,gc.log将被覆盖(例如,如果你重新启动tomcat,因为它有内存问题,你很想看到gc.log).或者至少它会旋转GC日志.控制gc日志记录还有很多其他选项.请参阅http://www.oracle.com/technetwork/articles/java/vmoptions-jsp-140102.html.特别要考虑`-XX:+ PrintGCDateStamps -XX:+ PrintGCTimeStamps -XX:+ UseGCLogFileRotation -XX:NumberOfGCLogFiles = <某些文件数> -XX:GCLogFileSize = <some size> -XX:+ PrintTenuringDistribution` (2认同)