进程内存与堆内存——JVM

9
我们有一个部署在tomcat服务器上的Web应用程序。我们运行一些特定的定时作业,之后堆内存升高并恢复到正常水平,所有看起来都很好。然而,系统管理员抱怨说随着计划任务增加,内存使用率(在Linux上的top命令)不断增加。堆内存和CPU内存之间有什么关联?它可以通过任何JVM设置进行控制吗?我使用JConsole监控系统。我通过JConsole强制进行了垃圾回收,堆使用量降低了,但是Linux上的内存使用量仍然很高并且没有下降。有任何想法或建议吗?

服务器显然是64位的。 - user546352
你知道服务器使用的是哪个JVM,以及在强制进行垃圾回收后堆内存使用和实际内存使用之间的区别吗? - Tim Stone
然而在Linux上,内存使用率仍然很高,从未降低。 "内存使用率"是指什么?垃圾回收通常不喜欢将内存返回给系统。 - bestsss
3个回答

10
JVM进程分配的内存与堆大小不同。使用的堆大小可能会下降,而JVM分配的空间实际上并没有减少。JVM必须接收触发器指示它缩小堆大小。如@Xepoch所述,这受-XX:MaxHeapFreeRatio 控制。
然而,系统管理员抱怨内存使用情况(Linux上的“top”)随着更多计划任务的运行而不断增加。
那是因为你很可能有某种内存泄漏。当系统管理员看到进程慢慢占用越来越多的空间时,他们倾向于抱怨。
有什么想法或建议吗?
你是否查看了线程数?你的应用程序是否创建自己的线程并将它们发送到死锁和无限等待中? 你是否集成任何第三方API,这些API可能使用JNI?

4
很可能观察到的是Java进程的虚拟大小而不是常驻集大小?如果你想要小的占用空间,你可能不想在JVM堆参数上包括-Xms或任何最小大小,并将70%的-XX:MaxHeapFreeRatio调整为更小的数字以允许更积极的堆收缩。

同时,提供更多关于Linux内存从未减少的细节是什么?使用了什么度量标准?


使用“top”命令时,尽管%MEM保持高位并随着更多的作业被调度而继续上升,但%CPU下降并且堆似乎正常。 - user546352
%MEM是RES相对于主内存的百分比,通常报告主内存中的驻留大小。 -Xms-Xmx选项是什么?还要计算% RES / VIRT和% RES / SHR并报告回来。它可能会报告很高,但进程可能有很大一部分是共享的。 - Jé Queue
这意味着略少于一半的内存实际上位于主内存中,其余部分要么未使用,要么已分页。如果 CPU 足够(您说它足够),并且考虑到 GC 遍历大部分堆的性质,我敢打赌您实际上只使用了该分配的百分比。而且不到 1% 的共享内存在这里可以忽略不计。 - Jé Queue
我将它设置为40,只是想看看是否有任何影响。 - user546352
@user546352 - JVM只是使用给定的资源。如果你想让它使用更少的资源,同时保持GC%开销在可控范围内,你需要告诉它使用更少的资源。如果你想进一步讨论,请通过我的个人资料与我联系。 - Jé Queue
显示剩余4条评论

0

您可以使用 -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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接