garbage-collection - 为什么需要 3 次 Full GC 来对 permgen 进行垃圾回收?

标签 garbage-collection java-7 permgen

为什么在perm gen被垃圾收集之前需要连续3次“Full GC”?

第一个 GC 将堆内存从 2.4gb 减少到 761mb,但没有实质性的 GC perm gen,尽管它似乎确实恢复了 6K。

我们将忽略年轻代集合。

第二次 Full GC 对堆的影响很小,正如预期的那样,因为当时服务器负载很轻。奇怪的是它对 perm gen 没有任何作用。

第三次 Full GC 最终将 perm gen 从其最大值 524mb 降至 141mb。

这是 GC 日志中未经编辑的片段:

2012-12-07T19:46:40.731-0600: [Full GC [CMS: 2474402K->761372K(2804992K), 4.6386780 secs]     2606228K->761372K(3111680K), [CMS Perm : 524286K->524280K(524288K)], 4.6387670 secs] [Times: user=4.68 sys=0.00, real=4.63 secs] 
2012-12-07T19:46:45.374-0600: [GC [ParNew
Desired survivor size 17432576 bytes, new threshold 6 (max 6)
- age   1:      65976 bytes,      65976 total
: 1552K->8827K(306688K), 0.0199700 secs] 762925K->770200K(3111680K), 0.0200340 secs]  [Times: user=0.08 sys=0.00, real=0.02 secs] 
2012-12-07T19:46:45.395-0600: [Full GC [CMS: 761372K->752917K(2804992K), 3.7379280 secs]  770212K->752917K(3111680K), [CMS Perm : 524287K->524287K(524288K)], 3.7380180 secs] [Times: user=3.77 sys=0.00, real=3.74 secs] 
2012-12-07T19:46:49.135-0600: [Full GC [CMS: 752917K->693347K(2804992K), 3.2845870 secs] 752917K->693347K(3111680K), [CMS Perm : 524287K->141759K(524288K)], 3.2846780 secs] [Times: user=3.32 sys=0.00, real=3.29 secs] 

系统信息和 Gcflags:

Java 1.7.0_07, 64-Bit Server, Ubuntu 12.04 
-Xms3g -Xmx3g -XX:PermSize=512m -XX:MaxPermSize=512m
-XX:+UseConcMarkSweepGC 

编辑:我们有两个应用服务器;第二个表现出稍微不同的行为:只有两个 Full GC 条目。

2012-12-07T20:36:31.097-0600: [Full GC [CMS: 2307424K->753901K(2804992K), 5.0783720 secs] 2394279K->753901K(3111680K), [CMS Perm : 524280K->524121K(524288K)], 5.0784780 secs] [Times: user=5.12 sys=0.00, real=5.08 secs] 
2012-12-07T20:36:36.178-0600: [Full GC [CMS: 753901K->695698K(2804992K), 3.4488560 secs] 755266K->695698K(3111680K), [CMS Perm : 524121K->140568K(524288K)], 3.4489690 secs] [Times: user=3.48 sys=0.00, real=3.45 secs] 

所以看起来年轻一代很重要。也许它需要两次连续的 Full GC,中间没有其他 GC(年轻代 GC)在我们的特定设置中对 perm gen 进行垃圾收集。我已经挖掘了很多,但我还没有找到任何关于这种行为的讨论。

最佳答案

heap 和 perm gen 的并发收集不会相互影响,这不会让我感到惊讶,尤其是堆收集本身已经是一个复杂的操作;这可以解释为什么 perm gen 只被第二次收集。不过,我主要是猜测。

获取更多有关 perm gen 中实际收集的内容(卸载的类、字符串?)的详细信息可能会很有趣。 -XX:+PrintGCDetails 会有所帮助,也许 -verbose:class。

关于garbage-collection - 为什么需要 3 次 Full GC 来对 permgen 进行垃圾回收?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13773954/

相关文章:

c - 对象之间的 Lua 引用

c# - 代表不收集垃圾

java - "generified"版本的JTree(TreeModel,TreeNode,...)会在JDK7中吗?

java - 关于 '&&' 和 '||' 优先级的混淆示例

java - PermGen 设置未生效

vb.net - 在 VB.NET 中复制字节数组

java - GC Clojure/Java/JVM 内存设置

java - 就地过滤 Java 列表,无需外部库

java - 解决使用 Jetty 7 重新部署时的 PermGen 问题

java - 你如何在 Java 中设计一个好的 permgen 空间字符串?