进程内存 vs 堆 -- JVM
Process Memory Vs Heap -- JVM
JVM中的内存问题是开发人员经常遇到的一个挑战。其中一个常见的问题是“Out of Memory”错误,这通常是由于堆内存不足导致的。为了解决这个问题,开发人员可以通过调整进程内存和堆内存的大小来增加可用内存。
在JVM中,可以使用-Xmx和-Xms参数来调整堆的大小。对于Tomcat,可以在启动之前设置一个环境变量,如下所示:
export JAVA_OPTS="-Xms256m -Xmx512m"
这将创建一个初始大小为256MB,最大大小为512MB的堆。
关于这个问题的更多细节可以参考以下链接:[http://confluence.atlassian.com/display/CONF25/Fix+Out+of+Memory+errors+by+increasing+available+memory](http://confluence.atlassian.com/display/CONF25/Fix+Out+of+Memory+errors+by+increasing+available+memory)
通过增加可用内存,开发人员可以解决“Out of Memory”错误,确保JVM有足够的堆内存来处理应用程序的需求。
问题的原因是Java进程的虚拟大小(virtual size)并非实际使用的大小(resident set size)。如果希望减小内存占用,可以不使用-Xms
或任何JVM堆参数中的最小大小,并将70%的-XX:MaxHeapFreeRatio=
调整为更小的值,以允许更积极地收缩堆大小。
同时,需要提供更多关于Linux内存没有减少的具体细节。使用'top'命令时,%MEM
保持较高,并且在安排更多作业时持续增加,而%CPU
则降低,堆表现良好。
%MEM
是占主内存的RES
的百分比,通常报告主内存中的驻留大小。请提供-Xms
和-Xmx
选项的值,并计算% RES/VIRT
和% RES/SHR
的百分比并反馈。可能报告较高,但进程可能有很大一部分是共享的。
我假设SHR
是以千字节为单位的,并且它是如何显示的。RES/VIRT
= 56%,RES/SHR
= 117.79,这是使用'M'选项的top输出。PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 14425 root 17 0 1990m 1.1g 9792 S 0.0 54.5 23:01.62 java 这是在我进行了你建议的-XX:MaxHeapFreeRatio更改之后,它似乎表现稍好,我仍然在运行一些测试。我注意到在运行作业时,CPU%超过了100%...
这意味着略少于一半的内存实际上是驻留在主内存中,其余部分要么未使用,要么被分页出去。如果CPU足够(你说是),并且考虑到GC遍历大部分堆内存的特性,我敢打赌你实际上只使用了该分配的百分比。并且不到1%是共享的,因此在这里可以忽略不计。
对于多进程和多线程应用程序来说,超过100% CPU是完全正常的(实际上,%CPU是一个不太准确的指标),请查看负载平均值。你将maxheapfreeratio
设置为什么值?
xmx
的值设置为1280,xms
保留默认值(未设置为任何数字)。
我将其设置为40,只是想看看是否有任何影响。
随着我安排更多作业,驻留内存正在增加,目前为1.5g(作业仍在运行)。其他参数保持不变,所以%RES/VIRT
= 77.5%,RES/SHR
仍然可以忽略不计。我注意到在某一点上,内存占用率超过了83%,然后降到了77.5%。你认为还有可能通过其他参数进一步降低它吗?感谢你的帮助。
JVM只使用给定的内存。如果希望减少内存使用量并保持GC%开销可控,请通过我的个人资料与我联系,以进一步讨论。
在解决这个问题之前,首先需要了解JVM进程的内存分配与堆大小之间的区别。JVM进程分配的内存与堆大小不同,即使堆的使用大小减少了,JVM分配的空间也不会减少。JVM需要接收一个触发器来指示它应该缩小堆的大小,这由“-XX:MaxHeapFreeRatio”参数控制。
然而,系统管理员抱怨在定时任务运行的越多的情况下,内存使用量(在Linux上的“top”命令中)不断增加。
这是因为很可能存在某种内存泄漏。当系统管理员看到进程逐渐消耗更多空间时,他们倾向于抱怨。
是否有任何想法或建议?
您是否查看了线程数量?您的应用程序是否创建了自己的线程并将它们发送到死锁并永远等待?
您是否与任何使用JNI的第三方API进行集成?