跟踪Java中的内存泄漏/垃圾回收问题
这是我几个月来一直试图寻找的问题。我有一个正在运行的Java应用程序,该应用程序处理xml提要并将结果存储在数据库中。存在间歇性的资源问题,很难追踪。 背景: 在生产包装盒(问题最明显的地方)上,我对包装盒的访问不是特别好,并且无法使Jprofiler运行。那个盒子是运行centos 5.2,tomcat6和java 1.6.0.11的64位四核8gb机器。它以这些java-opts开头 JAVA_OPTS="-server -Xmx5g -Xms4g -Xss256k -XX:MaxPermSize=256m -XX:+PrintGCDetails - XX:+PrintGCTimeStamps -XX:+UseConcMarkSweepGC -XX:+PrintTenuringDistribution -XX:+UseParNewGC" 技术堆栈如下: Centos 64位5.2 Java 6u11 雄猫6 Spring / WebMVC 2.5 休眠3 石英1.6.1 DBCP 1.2.1 的MySQL 5.0.45 高速缓存1.5.0 (当然还有许多其他依赖项,特别是jakarta-commons库) 我最能重现该问题的是内存需求较低的32位计算机。我确实可以控制。我已经使用JProfiler对其进行了探究,并修复了许多性能问题(同步问题,预编译/缓存xpath查询,减少线程池,删除不必要的休眠预取以及处理过程中过度的“缓存变暖”)。 在每种情况下,探查器都显示这些资源由于某种原因占用了大量资源,并且一旦进行更改,这些资源就不再是主要的资源消耗。 问题: JVM似乎完全忽略了内存使用设置,填满了所有内存并且变得无响应。这对于面对最终客户的客户来说是个问题,他们希望定期进行轮询(每5分钟一次,然后重试1分钟),对于我们的运营团队来说,这是不断得到通知的,盒子已变得没有响应,必须重新启动它。此框上没有其他可运行的东西。 问题似乎是垃圾回收。我们使用ConcurrentMarkSweep(如上所述)收集器是因为原始的STW收集器导致JDBC超时并变得越来越慢。日志显示,随着内存使用量的增加,即开始引发cms故障,并踢回原始的世界停止收集器,然后该收集器似乎未正确收集。 但是,使用jprofiler运行时,“运行GC”按钮似乎可以很好地清理内存,而不是显示增加的占用空间,但是由于我无法将jprofiler直接连接到生产盒,并且无法解决已证明的热点问题,因此我正在使用剩下的是将Garbage Collection调为盲人的巫毒教。 我试过的 分析和修复热点。 使用STW,Parallel和CMS垃圾收集器。 以最小/最大堆大小以1 / 2、2 / 4、4 / …