我们有一个java应用程序作为长期运行服务(此JVM的实际正常运行时间为31天3小时35分钟)
由于Windows任务管理器,该过程使用 1,075,384,320 B - 接近1 GB。
JVM的堆大小限制为 256 MB(-Xmx256m)
内存数据
Memory:
Size: 268,435,456 B
Max: 268,435,456 B
Used: 100,000,000 up to 200,000,000 B
- 此处没有泄漏
缓冲池
Direct:
Count: 137
Memory Used and Total Capacity: 1,348,354 B
Mapped:
Count: 0
Memory Used and Total Capacity: 0 B
- 此处没有泄漏
我的问题: JVM在哪里使用额外的内存?
其他信息:
Java: version 1.8.0_74 32 bit (Oracle)
Classes:
Total loaded: 17,248
Total unloaded: 35,761
Threads:
Live: 273
Live peak: 285
Daemon: 79
Total started: 486,282
重新启动后,流程大小需要几天时间才能增长,因此定期重启会有所帮助,也许使用较新的java版本也可以解决问题,但我想对此行为有一个解释,即G。 111之前的1.8.0中的已知错误,修复了... - 我没有找到任何东西,但是。
我们在不同的地方使用了大约350个这样的装置,所以改变并不容易。
答案 0 :(得分:0)
堆外内存消耗有两个常见原因:
sun.misc.Unsafe
进行“巧妙”使用。您可以使用jcmd
as explained here验证此跟踪本机内存使用情况(您需要重新启动应用程序)。
答案 1 :(得分:0)
不要忘记在长时间运行的任务中以服务器模式运行JVM!
这种内存泄漏的原因是JVM在客户端模式下运行。 我们的解决方案在旧的Windows XP 32位PC上的几个连锁店中运行。 此平台上的JVM默认为客户端模式。
在大多数情况下,我们运行JRE 1.8.0_74-32bit。在我们的应用程序中,这个JVM在“Thread Arena Space”中泄漏内存 - 似乎没有任何回报。
通过在JVM上设置参数-server
切换到服务器模式后,问题就消失了。