我跑到下面的方法调用Runtime.getRuntime()。maxMemory()而得到85196800。
然而,我再从顶部在命令行中运行,它显示
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
8672 root 20 0 1284m 156m 4296 S 0.3 60.9 0:33.35 java
没有这个节目的RAM 156M使用呢? 任何想法是怎么回事?
从文档,
maxMemory() - 返回Java虚拟机将尝试使用的最大内存量。
前只显示系统已分配给进程中的(虚拟)内存量 - 你问Java的多少也可以尝试在最坏的情况下使用。
一般情况下,查询信息的JVM和/或系统上使用的实际存储器是不可靠的。 例如,上面的数字可能包括内存分配但未使用或调出。 它也可以包括像共享库,其中10MB库可算作两个进程的拨款,但只有一个物理拷贝到内存中。 (例如)
你想做什么?
该方法的javadoc是错误的,或者至少是非常误导的。 这Sun错误报告解释说。
另一点是,示出为RES的156MB是当前的“驻留集”大小; 即物理RAM的数量目前归因于应用程序。 这个数字是容易因系统服务/守护程序和在计算机上运行的应用程序的虚拟内存需求的增加和减少。 该JVM声称报告中的数字是JVM的虚拟内存分配。
我只想说,这是所有的都不清晰,而且很可能不值得你的努力,试图弄明白。 如果你真的关心,要注意什么top
, vmstat
等告诉你,而忽视了JVM的数字。
调用Runtime.getRuntime()。maxMemory()被返回的最大的堆大小,而不是将由整个过程中消耗的存储器总量的估计值。 本机内存,本机库等,将有助于进程大小而不是maxMemory()。
如果你想了解为什么顶部显示消耗比JVM设置更多的内存。
这是我在过去的经验
我们已经看到,TOP和显示消耗比我们在JVM PARAMS最初设置更多的内存其他类似工具。
在我们的例子环境:AIX / WebSphere应用服务器。
原因是:我们在类路径,我们在我们的应用程序使用定义的一个共享库。 这种特殊的图书馆(PureedgeAPI) 实际上跨越了另一个进程或使得JNI调用 。 (很少.SO库为清楚起见),我们几个不正确的呼叫后 - 我的意思是不通过调用这个objects.destroy()不只是将它设置为NULL破坏。 我们已经看到了内存提高到30GB的水平上JVM拥有2GB(最大集)
从操作系统的角度 :因为JAVA是原来的过程-这JNI调用的所有子实例也被记录作为正在使用它的同一个Java父进程。
我没有方便的命令 - 但我居然会看到这一特定过程的树(这可能催生另一个进程(在你的情况下,JAVA))。
谢谢,