是什么原因导致 JRE 6 JVM 代码缓存泄漏?

2022-09-03 02:59:33

自从切换到 JRE 6 以来,我的服务器的代码缓存使用量(非堆)一直在无限期地增长。我的应用程序在运行时创建了很多类,但这些类在GC过程中成功卸载。我可以看到这些类在gc日志中被卸载,并且permGen的使用率保持不变。我特别确保在我的代码中,一旦我完成了这些类,它们就是孤立的,因此它们正确地从permGen中收集垃圾。

然而,代码缓存不断增长。我只是在切换到JRE 6后才意识到代码缓存。所以我想我的问题是:

  1. GC 是否包含代码缓存?
  2. 具体而言,可能导致代码缓存内存泄漏的原因。
  3. JDK 6 在这方面是否存在错误?

答案 1

您可能希望浏览此讨论,然后回过头来看看可能有助于缩小范围的内容:http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2009-January/000530.html

这个涉及JDK5,但可能会有所帮助:http://www.nabble.com/Java-code-cache-memory-td22202283.html

你是用它来编译jsp页面,还是类似的东西?如果没有,在应用程序启动后正在编译什么?您是否将AspectJ与运行时编织一起使用?

了解您正在做的事情将有助于更好地了解如何帮助。

此外,当代码缓存耗尽时,它是停止重新编译还是jvm崩溃?我会期待前者。

你使用的是 Sun 的 JDK 吗?我猜你是,因为我怀疑其他人被列为版本6,但问这个问题并没有什么坏处。


答案 2

我会寻找问题的两个可能的地方:泄漏的装载机和Massive String interning。

从您的应用程序描述中,我更有可能验证GC是否正在卸载旧的生成的类。

我不认为jConsole有办法可视化这一点,但是如果你能得到一个YourKit的副本,它有一种图形化的方式来检测上述两个问题。


推荐