我们有一个在Solaris 10上运行的Java进程,为约200-300个并发用户提供服务。管理员报告说,进程使用的内存随着时间的推移显著增加。几天后它就会达到2GB,而且不断增长。
我们已经转储了堆,并使用Eclipse Memory Profiler进行了分析,但未能发现任何异常情况。堆大小非常小。
在将内存状态日志添加到我们的应用程序后,我们发现管理员使用的“top”实用程序报告的内存使用情况与MemoryMXBean和Runtime库报告的使用情况存在差异。
下面是两者的输出。
Memory usage information
From the Runtime library
Free memory: 381MB
Allocated memory: 74MB
Max memory: 456MB
Total free memory: 381MB
From the MemoryMXBean library.
Heap Committed: 136MB
Heap Init: 64MB
Heap Used: 74MB
Heap Max: 456MB
Non Heap Committed: 73MB
Non Heap Init: 4MB
Non Heap Used: 72MB
Current idle threads: 4
Current total threads: 13
Current busy threads: 9
Current queue size: 0
Max threads: 200
Min threads: 8
Idle Timeout: 60000
PID USERNAME NLWP PRI NICE SIZE RES STATE TIME CPU COMMAND
99802 axuser 115 59 0 2037M 1471M sleep 503:46 0.14% java
这怎么可能呢?top命令报告的使用情况要高得多。我原本以为RES应该接近堆和非堆内存之和。
然而,pmap -x报告的大部分内存都在堆中:
Address Kbytes RSS Anon Locked Mode Mapped File
*102000 56 56 56 - rwx---- [ heap ]
*110000 3008 3008 2752 - rwx---- [ heap ]
*400000 1622016 1621056 1167568 - rwx---- [ heap ]
*000000 45056 45056 45056 - rw----- [ anon ]
有人能否请解释一下这个问题?我完全不知道该怎么做。
谢谢。
更新
在Linux上似乎没有这个问题。
另外,根据Peter Lawrey的回答,“pmap”报告的“堆”是本地堆而不是Java堆。