我有一个java程序已经运行了几天,它处理传入的消息并转发出去。
我今天注意到的一个问题是,我通过runtime.totalmemory()打印的堆大小仅显示~200m,但top命令中的res列显示它占用了1.2GRAM。
程序没有使用直接字节缓冲区。
我怎样才能找出jvm占用这么多额外ram的原因?
其他信息:
我正在使用openjdk-1.8.0
我没有设置任何jvm选项来限制堆大小,启动命令很简单:java-jar my.jar
我尝试使用jcmd进行堆转储,转储文件大小只有15米左右。
我试过pmap,但似乎有太多的信息打印,我不知道他们是有用的。
2条答案
按热度按时间gojuced71#
有一点是,如果堆占用的内存不多,那么可以从探查器工具检查非堆内存占用了多少内存。如果这个数量很高,甚至在gc循环之后,如果它没有下降,那么您可能应该查找内存泄漏(非堆)。
如果非堆内存占用不多,并且当您使用分析工具查看内存时,一切看起来都很好,那么我猜是jvm保存内存而不是释放内存。因此,您最好检查gc是否完全不工作,或者gc是否正在使用分析工具强制执行,内存是否下降,它是否扩展,或者发生了什么。jvm内存和堆内存有两种不同的行为,jvm可以假设它应该在基于
以上参数。因此,这背后的基本概念是,在gc循环之后,jvm开始获得空闲内存和已用内存的度量,并开始根据上述jvm标志的值进行自我扩展或收缩。默认情况下,它们被设置为40和70,您可能会对此感兴趣。这在集装箱环境中尤其重要。
snvhrwxg2#
您可以使用visualvm来监视jvm中发生的事情。您还可以使用jconsole进行主要概述。它与jdk本身一起提供。如果jdk是用环境变量设置的,那么从terminal开始使用
jconsole
. 然后选择应用程序并开始监视。