我们在Grails应用程序中面临一个奇怪的问题。总内存消耗在很短的时间内就会出现。它运行良好很长一段时间,但在某些时候,内存消耗只会上升,直到没有更多的内存消耗(Xmx)。它可能会在5分钟内从4 GB消耗增加到20 GB。消耗完整个内存后,tomcat就会无法响应。即使单独留下它也不会自行跟踪。在某些时候,我会期待一个OutOfMemory异常。但即使我们不接触应用程序也不会发生这种情况。我可以看到垃圾收集器继续运行(我们正在使用New relic),但消耗的内存仍然不会消失。
当我们注意到垃圾收集发生了一次重大打击时,我们将垃圾收集器从ConcurrentMarkSweep更改为G1GC。但也没有帮助。为了分析无响应的jvm,我们进行了一个线程转储,发现没有死锁,而且我们的很多线程都处于“阻塞”状态:
Thread 6632: (state = BLOCKED)
- sun.misc.Unsafe.park(boolean, long) @bci=0 (Compiled frame; information may be imprecise)
- java.util.concurrent.locks.LockSupport.park(java.lang.Object) @bci=14, line=186 (Compiled frame)
- java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await() @bci=42, line=2043 (Compiled frame)
- java.util.concurrent.LinkedBlockingQueue.take() @bci=29, line=442 (Compiled frame)
- org.apache.tomcat.util.threads.TaskQueue.take() @bci=36, line=104 (Interpreted frame)
- org.apache.tomcat.util.threads.TaskQueue.take() @bci=1, line=32 (Interpreted frame)
- java.util.concurrent.ThreadPoolExecutor.getTask() @bci=156, line=1068 (Interpreted frame)
- java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) @bci=26, line=1130 (Compiled frame)
- java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=5, line=615 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=724 (Interpreted frame)
这些线程中只有少数处于“IN_NATIVE”状态。
我们甚至使用jmap进行了内存转储,最常用的类看起来像这样:
我们正在使用Grails 2.3.8和MongoDB Plugin 3.0.1 for GORM。我们使用Memcached在tomcat7和Redis上进行会话共享以进行缓存(spring-cache和native redis)。
我们的服务器详细信息是:
Server version: Apache Tomcat/7.0.35
Server built: May 24 2013 09:52:20
Server number: 7.0.35.0
OS Name: Linux
OS Version: 3.8.0-19-generic
Architecture: amd64
JVM Version: 1.7.0_25-b15
JVM Vendor: Oracle Corporation
我们真的没有关于如何解决这个问题的想法。寻找解决此问题的帮助/指示。