2017-08-24 91 views
0

我已经阅读了大量的文章,但很明显我错过了我的理解。我有一个Tomcat服务,它安装有:Tomcat的服务内存超过了最大值,没有失败

--JvmMx=1000 
--JvmMs=128 

我已经验证,这些设置都可以通过电话,如成功:

PsExec.exe -s {jdk}\bin\jinfo.exe -flag MaxHeapSize {pid} 

然而,该服务始终如一的tomcat7.exe过程增长,超过这个最大的因素3或更多,直到它带来的服务器爬行。奇怪的是,这只是一台服务器上的问题。在其他地方它是相当稳定的并且保持在极限之下。我也在我的开发环境中寻找内存泄漏,但没有发现任何内存泄漏。

要调试这一点,我已经试过迫使GC像这样:

PsExec.exe -s {jdk}\bin\jcmd.exe {pid} GC.run 

但这似乎没有任何效果。所以接下来我将它设置为JConsole监视加入这个到安装:

tomcat7.exe //US//%SERVICE_NAME% ++JvmOptions="-Dcom.sun.management.jmxremote" 
tomcat7.exe //US//%SERVICE_NAME% ++JvmOptions="-Dcom.sun.management.jmxremote.port=8086" 
tomcat7.exe //US//%SERVICE_NAME% ++JvmOptions="-Dcom.sun.management.jmxremote.ssl=false" 
tomcat7.exe //US//%SERVICE_NAME% ++JvmOptions="-Dcom.sun.management.jmxremote.authenticate=false" 

现在是乖巧的(当然!)。 GC显然工作并且进程内存低于限制。

我很困惑。最大堆是1 GB,永久内存是90 MB,堆栈大小是默认的,那么大约128KB?线程数量不增长,仅为“67”。那么进程内存如何能够升至3+ GB呢?为什么它不抛出内存异常?

即使现在,根据jconsole的“良好行为”服务仅使用大约50 MB的堆,运行在57个线程上。然而任务管理器显示使用800 MB的71个线程。我认为差异是由于Tomcat,是吗?请帮我填补我的理解空白。

回答

1

Java使用比你需要的东西的Java堆空间更多的内存。它被称为“本地内存”,并不包含在您提及/检查的任何内存空间中。

这个职位将打开你的眼睛: http://www.evanjones.ca/java-native-leak-bug.html

(FWIW,对于一个服务器进程设置-Xms-Xmx不同的价值观根本就是浪费时间将它们设置为相同的值,使堆没有按”。如果你打算在服务器进程中配置1GiB,那么你可以立即使用它。)

+0

感谢您的链接。那很有意思!虽然我不知道它是否适用于此。该服务大多未被使用,因此它只是通过检查数据库以执行并记录状态来循环。当然没有太多的并发。我想DB调用可能是本地的。 JVM代码会变得如此之大似乎很奇怪。有没有办法限制这种增长? – Didjit

+0

至于你Xms/Xmx点,是的,我完全同意。 – Didjit

+0

@Didjit我无法知道如何限制JVM使用的本机内存的大小,而不限制OS级别的进程内存 - 如果它超过了限制,这当然会终止进程。它实际上不会让JVM保持在这样的限制之下。 –

相关问题