此问题特别针对在Linux x86-64上运行的Sun Java JVM 。我试图找出为什么即使我设置了Heap和Non-Heap限制,Sun JVM也会占用系统的大量物理内存。
我正在运行的程序是带有多个插件/功能的Eclipse 3.7。最常用的功能是PDT,EGit和Mylyn。我使用以下命令行开关启动Eclipse:
-nosplash -vmargs -Xincgc -Xms64m -Xmx200m -XX:NewSize=8m -XX:PermSize=80m -XX:MaxPermSize=150m -XX:MaxPermHeapExpansion=10m -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -XX:+UseParNewGC -XX:+CMSIncrementalMode -XX:+CMSIncrementalPacing -XX:CMSIncrementalDutyCycleMin=0 -XX:CMSIncrementalDutyCycle=5 -XX:GCTimeRatio=49 -XX:MaxGCPauseMillis=50 -XX:GCPauseIntervalMillis=1000 -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+DoEscapeAnalysis -XX:+UseCompressedOops -XX:+AggressiveOpts -Dorg.eclipse.swt.internal.gtk.disablePrinting
值得注意的是特别是开关:
-Xms64m -Xmx200m -XX:NewSize=8m -XX:PermSize=80m -XX:MaxPermSize=150m
这些交换机应将JVM堆限制为最大200 MB,将非堆限制为150 MB (“CMS永久生成”和“代码缓存”,由JConsole标记)。从逻辑上讲,JVM应该总共需要350 MB加上JVM所需的内部开销。
实际上,我的当前Eclipse进程的JVM需要544.6 MB ,由ps_mem.py(http://www.pixelbeat.org/scripts/ps_mem.py)计算,它计算Linux 2.6+内核保留的实际物理内存页面。 内部Sun JVM开销为35%或大约200MB!
有关如何减少此开销的任何提示?
以下是其他一些信息:
$ ps auxw
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
me 23440 2.4 14.4 1394144 558440 ? Sl Oct12 210:41 /usr/bin/java ...
根据JConsole,该进程使用了160 MB的堆和151 MB的非堆。
我并不是说我无法负担使用额外的200MB来运行Eclipse,但是如果有办法减少浪费,我宁愿使用200MB用于内核块设备缓冲区或文件缓存。另外,我和其他Java程序有类似的经验 - 也许我可以通过类似的调整来减少所有这些程序的开销。
更新:发布问题后,我发现上一篇文章到SO:
Why does the Sun JVM continue to consume ever more RSS memory even when the heap, etc sizes are stable?
我似乎应该使用pmap
来调查此问题。
答案 0 :(得分:3)
我认为Eclipse环境的高内存消耗的原因是使用SWT。 SWT是一个生活在JVM堆之外的本机图形库,为了使情况恶化,Linux上的实现并没有真正优化。
我认为没有机会减少eclipse环境中关于堆外部内存的内存消耗。
答案 1 :(得分:1)
Eclipse是一个内存和CPU。除了Java类库之外,所有低端GUI内容都由本机系统调用处理,因此您将拥有一个实质的“本机”JNI库来执行附加到您的进程的低级X术语调用。
Eclipse提供了数以百万计的有用功能和大量助手来加速您的日常编程任务 - 但精益而非意味着它不是。内存或资源的任何减少都可能导致明显的减速。这实际上取决于你对计算机内存的重视程度。
如果你想要精益和平均gvim和make是无与伦比的。如果你想要代码完成,自动构建等,你必须期望用额外的资源来支付。
答案 2 :(得分:0)
如果我运行以下程序
public static void main(String... args) throws InterruptedException {
for (int i = 0; i < 60; i++) {
System.out.println("waiting " + i);
Thread.sleep(1000);
}
}
带有ps auwx
打印的
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
500 13165 0.0 0.0 596680 13572 pts/2 Sl+ 13:54 0:00 java -Xms64m -Xmx200m -XX:NewSize=8m -XX:PermSize=80m -XX:MaxPermSize=150m -cp . Main
使用的内存量为13.5 MB。大约200 MB的共享库计入VSZ大小。其余的可以在max heap,max perm gen中计算,其中包含线程堆栈的开销等。
问题似乎不是JVM,而是运行在其中的应用程序。使用其他共享库,直接内存和内存映射文件可以增加使用的内存量。
鉴于您可以以100美元左右的价格购买16 GB,您知道这实际上是一个问题吗?