【问题标题】:JVM leaking memory when the G1 collector is used?使用 G1 收集器时 JVM 泄漏内存?
【发布时间】:2012-06-17 20:28:07
【问题描述】:

有没有人在使用 G1 收集器时遇到 JVM(Hotspot)泄漏内存的问题?

我已将堆大小固定为 60GB(-ms 和 -ms 都设置为 60G),但 java 进程的大小(根据 ps 命令的 vsz 列)从 64GB 左右开始,但是在 7 小时内增加到 84GB。

使用并行收集器,进程大小在 20 小时运行后保持稳定,约为 65GB。

G1 收集器是否有其他人遇到过类似问题?我正在运行一个非常简单的基准测试,并且我没有使用任何直接缓冲内存或其他堆外内存(我知道)。

Java版本为1.7.0,更新5

(我已经向 Oracle 提出了一个关于此问题的错误,但我想我也会在这里检查一下,以防有人有解决方法)。

【问题讨论】:

  • 将您的问题发送到hotspot-gc-dev@openjdk.java.net。
  • @Neil 你能告诉我们你使用的是哪个 Java 版本吗?
  • @alain.janinm 当然,现在是 1.7.0,更新 5。我已经更新了问题。
  • 测试中不涉及直接缓冲区(顺便说一句,也有一种方法可以获取它们使用的内存量),也没有最终确定,LinkedList 的大小很小,所以没有问题。测试本身的一些编程问题:对于“有界”LHM,您可以使用受保护的方法removeEldestEntry,但这与测试无关,存在数据竞争和不需要的同步。处理统计数据。然而,所有这些都不会影响测试。

标签: java garbage-collection jvm jvm-hotspot g1gc


【解决方案1】:

有没有其他人在使用 G1 收集器时遇到过类似的问题?

很快 - 是的。

这是关于导致内存泄漏的主题:

Creating a memory leak with Java

它包含有关 G1

的信息

使用 InflaterInputStream 传递 new java.util.zip.Inflater() 在 c-tor(例如 PNGImageDecoder)而不是调用 end() 充气机。好吧,如果您通过新的 c-tor 传递,则没有机会... 是的,在流上调用 close() 不会关闭充气机,如果它是 作为 c-tor 参数手动传递。这不是真正的泄漏,因为它会 由终结器释放......当它认为有必要时。直到那个 当它严重消耗本机内存时,它可能导致 linux oom_killer 肆无忌惮地扼杀进程。主要问题是最终确定 java 非常不可靠,G1 在 7.0.2 之前让它变得更糟。道德的 故事:尽快释放原生资源,终结器是 太穷了。

这里也提到了泄漏:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7152954

【讨论】:

  • 非常感谢您提供的信息。我没有使用充气机,也没有显式调用 System.gc() (而且我很确定我使用的也不是),所以我认为我看到的问题与任何一个。
  • @Neil 真的很难说出哪里出了问题。内存泄漏总是让人头疼:)
  • @Neil,我是发布 G1 问题的人,您使用哪个版本?最重要的是,它会泄漏本机内存吗?直接 ByteBuffers 类似于 Inflater/Deflater(它们使用本机 C 内存/malloc)。 System.gc() 总体来说还不错。如果它不是本机内存, jmap -histo 应该足以跟踪问题。此外,如果您可以发布基准测试,它会很有用。
  • 是的,它似乎正在泄漏本机内存——它肯定不是堆内存,因为在整个测试过程中我的堆上大约有 10GB 空闲空间(发生 GC 之后)。
  • 我没有直接使用直接字节缓冲区(而且我的测试非常简单,所以如果我调用任何这样做的东西,我会感到惊讶)。以防万一,我设置了 -XX:MaxDirectMemorySize=1G。代码在这里:gist.github.com/2947570
猜你喜欢
  • 1970-01-01
  • 2018-05-10
  • 2012-01-03
  • 1970-01-01
  • 2014-05-29
  • 1970-01-01
  • 1970-01-01
  • 2012-06-28
  • 1970-01-01
相关资源
最近更新 更多