Java Runtime.maxMemory不正确?
我运行了以下方法 Runtime.getRuntime().maxMemory() 并给予 85196800 然而,我从命令行运行top,结果显示Java Runtime.maxMemory不正确?,java,performance,optimization,memory,memory-leaks,Java,Performance,Optimization,Memory,Memory Leaks,我运行了以下方法 Runtime.getRuntime().maxMemory() 并给予 85196800 然而,我从命令行运行top,结果显示 PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 867
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吗?有什么想法吗?来自文档 maxMemory()- 返回Java虚拟机将尝试使用的最大内存量 Top仅显示系统分配给进程的(虚拟)内存量——您询问Java在最坏情况下可以尝试使用多少内存 通常,向JVM和/或系统查询实际使用内存的信息是不可靠的。例如,top的数字可能包括已分配但未使用或已分页的内存。它还可以包括共享库之类的东西,在共享库中,10MB的库可以计算两个进程的分配,但内存中只有一个物理副本。(例如)
您想做什么?从文档中 maxMemory()- 返回Java虚拟机将尝试使用的最大内存量 Top仅显示系统分配给进程的(虚拟)内存量——您询问Java在最坏情况下可以尝试使用多少内存 通常,向JVM和/或系统查询实际使用内存的信息是不可靠的。例如,top的数字可能包括已分配但未使用或已分页的内存。它还可以包括共享库之类的东西,在共享库中,10MB的库可以计算两个进程的分配,但内存中只有一个物理副本。(例如)
您想做什么?Runtime.getRuntime().maxMemory()返回的是最大堆大小的估计值,而不是整个进程将消耗的内存总量。本机内存、本机库等将影响进程大小,但不会影响maxMemory()。Runtime.getRuntime().maxMemory()返回的是最大堆大小的估计值,而不是整个进程将消耗的内存总量。本机内存、本机库等会影响进程大小,但不会影响maxMemory()。这就解释了 另一点是,显示为RES的156Mb是当前的“常驻集”大小;i、 e.当前归属于应用程序的物理RAM量。根据计算机上运行的系统服务/守护进程和应用程序的虚拟内存需求,此数字可能会增加或减少。JVM声称报告的数字是JVM的虚拟内存分配
我只想说,这一切都像泥一样清晰,可能不值得你努力去弄清楚。如果您真的在意,请注意
top
,vmstat
等告诉您的内容,并忽略JVM编号。该方法的Javadocs是错误的,或者至少是非常误导的。这就解释了
另一点是,显示为RES的156Mb是当前的“常驻集”大小;i、 e.当前归属于应用程序的物理RAM量。根据计算机上运行的系统服务/守护进程和应用程序的虚拟内存需求,此数字可能会增加或减少。JVM声称报告的数字是JVM的虚拟内存分配
我只想说,这一切都像泥一样清晰,可能不值得你努力去弄清楚。如果您真的在意,请注意
top
,vmstat
等告诉您的内容,忽略JVM编号。如果您试图理解为什么top显示的内存消耗量比JVM中设置的要多
这是我过去的经历
我们已经看到TOP和其他类似的实用程序显示了比我们最初在JVM参数中设置的更多的内存消耗
在我们的案例中,环境是:
AIX/Websphere应用服务器
原因是:
我们在应用程序中使用的类路径中定义了一个共享库。
这个特定的库(PureedgeAPI)实际上跨越另一个进程或进行JNI调用。
(为了清晰起见,很少有图书馆)
在我们进行了几次不正确的调用之后-我的意思是不通过调用这个对象进行销毁。destroy()不只是将其设置为NULL。我们已经看到,在2gb(最大设置)的jvm上,内存提升到30GB的水平
从操作系统的角度来看:由于JAVA是原始进程,因此此JNI调用的所有子实例也被记录为使用它的同一个JAVA父进程
我手头没有命令,但我会看到这个特定进程的树(这可能会产生另一个进程(在您的例子中是java))
谢谢,如果您想了解为什么top显示的内存消耗比jvm中的set要多 这是我过去的经历 我们已经看到TOP和其他类似的实用程序显示了比我们最初在JVM参数中设置的更多的内存消耗 在我们的案例中,环境是: AIX/Websphere应用服务器 原因是: 我们在应用程序中使用的类路径中定义了一个共享库。 这个特定的库(PureedgeAPI)实际上跨越另一个进程或进行JNI调用。 (为了清晰起见,很少有图书馆) 在我们进行了几次不正确的调用之后-我的意思是不通过调用这个对象进行销毁。destroy()不只是将其设置为NULL。我们已经看到,在2gb(最大设置)的jvm上,内存提升到30GB的水平 从操作系统的角度来看:由于JAVA是原始进程,因此此JNI调用的所有子实例也被记录为使用它的同一个JAVA父进程 我手头没有命令,但我会看到这个特定进程的树(这可能会产生另一个进程(在您的例子中是java)) <