Linux顶级输出不切实际?

时间:2017-03-24 15:34:05

标签: java linux

我在java进程中遇到了一个奇怪的问题,它在Linux VM上消耗了大量资源。 该过程的顶部输出如下:

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
1182 blabla     20   0 25.5g  21g  45m S 382.9 33.9 139840:17 java

所以这表明该过程实际上消耗了21G的物理内存?

当更详细地检查过程时,我可以看到它是用-Xmx4G启动的。对于" top"上显示的21G是否有任何合理的解释? ? (忽略下面ps输出的第一个-Xmx)

blabla@dtraflocorh391:~ $ ps aux | grep 1182
blabla     1182  249 33.8 26716716 22363868 ?   Sl   Feb13 139847:01 java -Xms32M -Xmx128M -showversion -Djavax.xml.stream.XMLEventFactory=com.ctc.wstx.stax.WstxEventFactory -Djavax.xml.stream.XMLInputFactory=com.ctc.wstx.stax.WstxInputFactory -Djavax.xml.stream.XMLOutputFactory=com.ctc.wstx.stax.WstxOutputFactory -Xms256M -Xmx4G -verbose:gc -XX:+PrintGCTimeStamps ... ... ...

... ...

2 个答案:

答案 0 :(得分:2)

  

所以这表明该过程实际上消耗了21G的物理内存?

是。 "顶部"命令报告操作系统提供的进程物理内存使用情况。没有理由不信任它。

  

对于" top"上显示的21G是否有任何合理的解释? ?

可能是大量的堆外内存分配,或者是大型内存映射文件,或者......大量的线程堆栈。

或其他可能的东西。

请注意,VIRT数字表示已经以某种方式提交给进程的总虚拟内存。 ' RES'图表示用于保存' VIRT'的子集的总物理内存使用量。当前"在"。

中分页的数字

因此,VIRT图可以更好地衡量Java进程所要求的内存资源。事实上,VIRT和RES是如此不同,这一事实证明了你的过程导致了#th; thrashing"。

另见:

答案 1 :(得分:2)

-Xmx控制最大堆大小 - 实际上是存储使用new关键字创建的内容。

Java有其他内存池 - 用于执行堆栈,用于缓存JIT编译代码,用于存储加载的类和动态创建的类,用于内存映射文件,本机代码使用的堆空间(JNI,或者只是Hotspot本身) ):见How is the java memory pool divided?

JConsole是一个可用于查看Java程序使用内存的工具。一旦JConsole告诉你哪个区域大/满,你就可以开始说明为什么会这样了。

例如,我曾经有一个程序为每个解析加载一个新的Jackson对象映射器 - 而这个版本的Jackson有一个错误,它在非堆内存中留下了动态类,从来没有GCd。您的问题可能是这个,或者可能是完全不同的问题。 JConsole将告诉你。