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

时间:2009-10-18 21:16:55

标签: java memory-leaks jvm

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

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

  1. GC是否包含代码缓存?
  2. 具体是什么可能导致代码缓存内存泄漏。
  3. JDK 6中是否存在此区域的错误?

6 个答案:

答案 0 :(得分: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版,但是问这个问题并没有什么坏处。

答案 1 :(得分:1)

我想知道新的G1垃圾收集器(从Java 6更新14开始)是否可以帮助你。您可以尝试使用-XX:+ UnlockExperimentalVMOptions -XX:+ UseG1GC,但是根据comments on Jon Masamitsu's blog它不会(如果问题确实是由于代码缓存)。但也许那里的讨论或其中的链接可能有所帮助。

答案 2 :(得分:1)

来自此博文中的评论:http://blogs.oracle.com/jonthecollector/entry/our_collectors

  当卸载类时,

代码被驱逐(如   好吧,因为当方法“无效”时,即一些假设是   在他们的编译过程中不再持有)

如果我是你,我会运行一个工作负载,进行堆转储,并检查是否所有类都是你期望的gc。

答案 3 :(得分:1)

我会寻找问题的两个可能的地方:泄漏的装载机和大规模的字符串实习。

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

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

答案 4 :(得分:0)

是否可以针对麻烦的应用程序调用jvisualvm(在JDK中)?它可能会让你更加明智地了解正在发生的事情。

答案 5 :(得分:0)

  1. 不,但你可以使用-XX:+ UseCodeCacheFlushing标志让JVM在代码缓存填满时处理一些已编译的代码,尽管它有时并不那么有用。尝试-XX:ReservedCodeCacheSize和-XX:CompileThreshold。
  2. 不时热部署等。
  3. 了解详情:https://blog.codecentric.de/en/2012/07/useful-jvm-flags-part-4-heap-tuning/