Java Runtime.maxMemory不正确?

时间:2009-09-23 03:57:46

标签: java performance optimization memory memory-leaks

我运行了以下方法  调用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吗?有什么想法发生了什么?

4 个答案:

答案 0 :(得分:3)

从文档中

maxMemory() - 返回Java虚拟机将尝试使用的最大内存量。

Top仅显示系统已分配给进程的(虚拟)内存量 - 您要求Java在最坏的情况下尝试使用多少内容。

通常,查询JVM和/或系统以获取有关实际使用内存的信息是不可靠的。例如,top的数字可能包括已分配但未使用或已分页的内存。它还可以包括共享库之类的东西,其中10MB库可能会计入两个进程的分配,但内存中只有一个物理副本。 (例如)

你想做什么?

答案 1 :(得分:1)

该方法的Javadocs是错误的,或者至少是非常误导。这个Sun bug report解释了。

另一点是显示为RES的156Mb是当前的“驻留集”大小;即当前归因于该应用程序的物理RAM量。根据系统服务/守护程序和计算机上运行的应用程序的虚拟内存需求,此数字可能会增加或减少。 JVM声称要报告的数字是JVM的虚拟内存分配。

我只想说这一切都像泥巴一样清晰,并且可能不值得你努力去弄明白。如果您真的在意,请注意topvmstat等等告诉您的内容,并忽略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))。

谢谢,