ChatGPT解决这个技术问题 Extra ChatGPT

Java 垃圾收集日志消息

我已将 java 配置为将垃圾收集信息转储到日志 (verbose GC)。我不确定日志中的垃圾收集条目是什么意思。这些条目的示例发布在下面。我在 Google 上进行了搜索,但没有找到可靠的解释。

我有一些合理的猜测,但我正在寻找能够严格定义条目中数字含义的答案,并得到可靠来源的支持。对引用 sun 文档的所有答案自动 +1。我的问题是:

PSYoungGen 指的是什么?我认为这与上一代(年轻?)有关,但究竟是什么?第二个三元组和第一个有什么区别?为什么为第一个三元组指定了名称(PSYoungGen)而不是第二个?三元组中的每个数字(内存大小)是什么意思。比如109884K->14201K(139904K),就是GC前的内存109884k,然后降到14201K。第三个数字有什么关系?为什么我们需要第二组数字?

8109.128:[GC [Psyounggen:109884K-> 14201K(139904K)] 691015K-> 595332K(1119040K),0.0454530 secs] 81111:81111:秒] 8112.802: [GC [PSYoungGen: 130344K->3732K(118592K)] 720708K->607895K(1097728K), 0.0682690 秒]

整个堆,堆的年轻代部分,次要 gc 了解 gc 的工作原理,检查例如 cubrid.org/blog/dev-platform/…

a
approxiblue

PSYoungGen 指的是用于次要收集的垃圾收集器。 PS 代表并行清除。第一组数字是年轻代的前后大小,第二组数字是整个堆的。 (Diagnosing a Garbage Collection problem 详细说明格式)名称表示有问题的生成和收集器,第二组是针对整个堆的。

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

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

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

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

GC 前使用 107Mb,GC 后使用 14Mb,最大年轻代大小 137Mb

GC 前使用 675Mb 堆,GC 后使用 581Mb 堆,最大堆大小为 1Gb

Minor GC 发生在 JVM 启动后 8109.128 秒,耗时 0.04 秒


只是一个小评论,'()'之间的值不是最大尺寸,永远是目前的最大尺寸。如果 GC 无法释放更少的堆,则此限制将需要更多空间用于操作系统,并且此值将增加。当然尊重定义的限制:-Xmx
@rafa.ferreira 我认为括号中的值即 1119040K 是提交的堆大小。我不认为,GC 会在任何地方打印“最大堆”大小。 Reference 1Reference 2
a
approxiblue

其中大部分内容在 GC Tuning Guide 中进行了解释(无论如何您都应该好好阅读)。

命令行选项 -verbose:gc 导致在每次收集时打印有关堆和垃圾收集的信息。例如,这里是大型服务器应用程序的输出: [GC 325407K->83000K(776768K), 0.2300771 secs] [GC 325816K->83372K(776768K), 0.2454258 secs] [Full GC 267628K->83769K(7767684K), secs] 在这里,我们看到两个次要集合,然后是一个主要集合。箭头前后的数字(例如,第一行的 325407K->83000K)分别表示垃圾回收前后活动对象的组合大小。在次要收集之后,大小包括一些垃圾(不再存在)但无法回收的对象。这些对象要么包含在永久代中,要么从永久代或永久代中引用。括号中的下一个数字(例如,第一行的(776768K))是堆的提交大小:Java 对象在不向操作系统请求更多内存的情况下可用的空间量。请注意,此数字不包括幸存者空间之一,因为在任何给定时间只能使用一个,也不包括永久代,其中包含虚拟机使用的元数据。行中的最后一项(例如,0.2300771 秒)表示执行收集所花费的时间;在这种情况下,大约是四分之一秒。第三行主要集合的格式类似。 -verbose:gc 生成的输出格式可能会在未来版本中更改。

我不确定为什么你的里面有一个 PSYoungGen;你改变了垃圾收集器吗?


在哪里可以找到 gc 日志文件?
这个答案并没有真正解决最初的问题。我觉得迈克尔约瑟夫的回答更好。它解决了 Ethan 提出的问题,并且在分解原始示例方面做得更好。虽然他的回答中有两个问题(他的链接现在已经死了,rafa.ferreria 指出了另一个问题),但它不仅仅是反刍 Oracle 文档。
a
assylias

我只是想提一下,可以通过以下方式获取详细的 GC 日志

-XX:+PrintGCDetails 

范围。然后你会看到答案中的 PSYoungGen 或 PSPermGen 输出。

此外,-Xloggc:gc.log 似乎生成与 -verbose:gc 相同的输出,但您可以在第一个中指定一个输出文件。

示例用法:

java -Xloggc:./memory.log -XX:+PrintGCDetails Memory

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

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


请注意,当 java 重新启动时,gc.log 将被覆盖(例如,如果您重新启动您的 tomcat,因为它有内存问题,并且您希望看到 gc.log)。或者至少如果您轮换 GC 日志,它会。还有很多其他选项可以控制 gc 日志记录。请参阅oracle.com/technetwork/articles/java/vmoptions-jsp-140102.html。特别是考虑 -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<some number of files> -XX:GCLogFileSize=<some size> -XX:+PrintTenuringDistribution