我运行了以下方法 调用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
这不显示使用了156M的ram吗?有什么想法发生了什么?
答案 0 :(得分:3)
从文档中
maxMemory() - 返回Java虚拟机将尝试使用的最大内存量。
Top仅显示系统已分配给进程的(虚拟)内存量 - 您要求Java在最坏的情况下尝试使用多少内容。
通常,查询JVM和/或系统以获取有关实际使用内存的信息是不可靠的。例如,top的数字可能包括已分配但未使用或已分页的内存。它还可以包括共享库之类的东西,其中10MB库可能会计入两个进程的分配,但内存中只有一个物理副本。 (例如)
你想做什么?
答案 1 :(得分:1)
该方法的Javadocs是错误的,或者至少是非常误导。这个Sun bug report解释了。
另一点是显示为RES的156Mb是当前的“驻留集”大小;即当前归因于该应用程序的物理RAM量。根据系统服务/守护程序和计算机上运行的应用程序的虚拟内存需求,此数字可能会增加或减少。 JVM声称要报告的数字是JVM的虚拟内存分配。
我只想说这一切都像泥巴一样清晰,并且可能不值得你努力去弄明白。如果您真的在意,请注意top
,vmstat
等等告诉您的内容,并忽略JVM编号。
答案 2 :(得分:0)
Runtime.getRuntime()。maxMemory()返回最大堆大小的估计值,而不是整个进程将消耗的内存总量。本机内存,本机库等将有助于进程大小,但不会对maxMemory()有所贡献。
答案 3 :(得分:0)
如果你试图理解为什么top显示的内存消耗比jvm中设置的更多。
这是我过去的经历
我们已经看到TOP和其他类似的实用程序显示比我们最初在JVM参数中设置的内存消耗更多。
在我们的案例中,环境是: AIX / Websphere应用程序服务器。
原因是: 我们在Classpath中定义了一个共享库,我们在应用程序中使用它。 此特定库(PureedgeAPI)实际上跨越另一个进程或进行JNI调用。 (为清楚起见,很少有.SO库) 在我们几乎没有错误的调用之后 - 我的意思是不通过调用这个objects.destroy()来破坏,而不仅仅是将其设置为NULL。我们已经看到内存在jvm上以2GB(最大设置)提升到30GB的水平
从操作系统的角度来看:由于JAVA是原始进程 - 此JNI调用的所有子实例也被记录为使用它的相同JAVA父进程。
我没有方便的命令 - 但我实际上会看到这个特定进程的树(这可能会产生另一个进程(在你的情况下为java))。
谢谢,