自切换到JRE 6后,我的服务器代码缓存使用率(非堆)不断增长。我的应用程序在运行时创建了很多类,但这些类在GC过程中成功卸载。我可以看到这些类在gc日志中被卸载,而permGen的使用也保持不变。我特别确保在我的代码中,一旦我完成它们,这些类就会被孤立,因此它们正确地从permGen收集垃圾。
然而,代码缓存不断增长。切换到JRE 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)
了解详情:https://blog.codecentric.de/en/2012/07/useful-jvm-flags-part-4-heap-tuning/