我读了很多帖子,但显然我在理解中遗漏了一些东西。我有一个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,是吗?请帮助我填补我理解的空白。
答案 0 :(得分:3)
Java使用的内存多于Java堆空间所需的内存。它被称为"本地记忆"并且在您提及/检查的任何存储空间中都没有计算。
这篇文章会睁开眼睛: http://www.evanjones.ca/java-native-leak-bug.html
(FWIW,将-Xms
和-Xmx
设置为服务器进程的不同值只是浪费时间。将它们设置为相同的值,这样堆就不需要了在路上重新调整了大量的时间" up"到最大堆大小。如果你打算将1GiB配置到服务器进程,你也可以立即使用它。)
答案 1 :(得分:0)
从我发现的官方文档:
- JvmMs初始内存池大小(MB)。 (不在exe模式下使用。)
- JvmMx最大内存池大小(MB)。 (不在exe模式下使用。)
https://tomcat.apache.org/tomcat-8.5-doc/windows-service-howto.html
如果您还没有
,请尝试添加--StartMode jvm --Jvm