我们在Solaris 10上运行了一个java进程,为大约200-300个并发用户提供服务.管理员报告说,进程使用的内存会随着时间的推移而显着增加.它在几天内达到2GB,并且永远不会停止增长.
我们已经倾倒堆和使用Eclipse内存分析器进行分析,但无法看到任何不寻常那里.堆大小非常小.
增加内存统计记录之后,我们的应用,我们发现通过"顶"工具,管理员使用,并通过MemoryMXBean和运行时库报道的使用报告的内存使用量之间的差异.
这是两者的输出.
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
Run Code Online (Sandbox Code Playgroud)
怎么会这样?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 ]
Run Code Online (Sandbox Code Playgroud)
任何人都可以对此有所了解吗?我完全迷失了.
谢谢.
更新
这似乎不是Linux上的问题.
另外,根据Peter Lawrey的回应,pmap报告的"堆"是本机堆而不是Java堆.
在垃圾收集环境中,保留未使用的指针相当于“泄漏失败”并阻止 GC 完成其工作。很容易意外地保留指针。
一个常见的罪魁祸首是哈希表。另一种是逻辑上清除的数组或向量(通过将重用索引设置为 0),但数组的实际内容(在使用索引之上)仍然指向某些内容。