如何减少Sun/Oracle JVM内部开销?

发布于 2024-12-10 15:52:51 字数 2026 浏览 0 评论 0 原文

此问题专门针对在 Linux x86-64 上运行的 Sun Java JVM。我试图找出为什么即使我设置了堆和非堆限制,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 Permanent”)生成”和“代码缓存”(由 JConsole 标记)。从逻辑上讲,JVM 总共应占用 350 MB 加上 JVM 所需的内部开销。

实际上,根据 ps_mem.py (http://www.pixelbeat.org/scripts/ps_mem.py),它计算 Linux 2.6+ 内核保留的真实物理内存页。 这是 35% 的内部 Sun JVM 开销,即大约 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 程序也有类似的经验——也许我可以通过类似的调整来减少所有这些程序的开销。

更新:发布问题后,我找到了之前的帖子: 为什么即使堆等大小稳定,Sun JVM 仍继续消耗更多的 RSS 内存? 看来我应该使用pmap来调查这个问题。

This problem is specifically about Sun Java JVM running on Linux x86-64. I'm trying to figure out why the Sun JVM takes so much of system's physical memory even when I have set Heap and Non-Heap limits.

The program I'm running is Eclipse 3.7 with multiple plugins/features. The most used features are PDT, EGit and Mylyn. I'm starting the Eclipse with the following command line switches:

-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

Worth noting are especially the switches:

-Xms64m -Xmx200m -XX:NewSize=8m -XX:PermSize=80m -XX:MaxPermSize=150m

These switches should limit the JVM Heap to maximum of 200 MB and Non-Heap to 150 MB ("CMS Permanent generation" and "Code Cache" as labeled by JConsole). Logically the JVM should take total of 350 MB plus the internal overhead required by the JVM.

In reality, the JVM takes 544.6 MB for my current Eclipse process as computed by ps_mem.py (http://www.pixelbeat.org/scripts/ps_mem.py) which computes the real physical memory pages reserved by the Linux 2.6+ kernel. That's internal Sun JVM overhead of 35% or roughly 200MB!

Any hints about how to decrease this overhead?

Here's some additional info:

$ 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 ...

And according to JConsole, the process has used 160 MB of heap and 151 MB of non-heap.

I'm not saying that I cannot afford using extra 200MB for running Eclipse, but if there's a way to reduce this waste, I'd rather use that 200MB for kernel block device buffers or file cache. In addition, I have similar experience with other Java programs -- perhaps I could reduce the overhead for all of them with similar tweaks.

Update: After posting the question, I found previous post to SO:
Why does the Sun JVM continue to consume ever more RSS memory even when the heap, etc sizes are stable?
It seems that I should use pmap to investigate the problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甜宝宝 2024-12-17 15:52:51

我认为Eclipse环境内存消耗高的原因是SWT的使用。 SWT 是一个位于 JVM 堆之外的原生图形库,更糟糕的是,Linux 上的实现并没有真正优化。

我不认为真的有机会减少关于堆外内存的 Eclipse 环境的内存消耗。

I think the reason for the high memory consumption of your Eclipse Environment is the use of SWT. SWT is a native graphic library living outside of the heap of the JVM, and to worsen the situation, the implementation on Linux is not really optimized.

I don't think there's really a chance to reduce the memory consumption of your eclipse environment concerning the memory outside the heap.

朮生 2024-12-17 15:52:51

Eclipse 非常消耗内存和CPU。除了 Java 类库之外,所有低端 GUI 内容均由本机系统调用处理,因此您将拥有一个重要的“本机”JNI 库来执行附加到进程的低级 X 术语调用。

Eclipse 提供了数百万个有用的功能和大量的帮助程序来加速您的日常编程任务 - 但它并不是精益和意味着。内存或资源的任何减少都可能导致速度明显减慢。这实际上取决于您对时间与计算机内存的重视程度。

如果你想要精益和平均,gvim 和 make 是无与伦比的。如果您想要代码完成、自动构建等,您必须为此付出额外的资源。

Eclipse is a memory and cpu hog. In addition to the Java class libraries all the low end GUI stuff is handled by native system calls so you will have a substantial "native" JNI library to execute the low level X term calls attached to your process.

Eclipse offers millions of useful features and lots of helpers to speed up your day to day programming tasks - but lean and mean it is not. Any reduction in memory or resources will probably result in a noticeable slowdown. It really depends on how much you value your time vs. your computers memory.

If you want lean and mean gvim and make are unbeatable. If you want the code completion, automatic builds etc. you must expect to pay for this with extra resources.

徒留西风 2024-12-17 15:52:51

运行以下程序,

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 大小。其余的可以算在最大堆、最大永久代以及线程堆栈等的开销中。

问题似乎不在于 JVM,而在于其中运行的应用程序。使用额外的共享库、直接内存和内存映射文件可以增加内存使用量。

鉴于您可以花费大约 100 美元购买 16 GB,您知道这实际上是一个问题吗?

If I run the following program

public static void main(String... args) throws InterruptedException {
    for (int i = 0; i < 60; i++) {
        System.out.println("waiting " + i);
        Thread.sleep(1000);
    }
}

with ps auwx prints

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

The amount of memory used is 13.5 MB. There about 200 MB of shared libraries which counts towards the VSZ size. The rest can be acounted for in the max heap, max perm gen with an overhead for the thread stacks etc.

The problem doesn't appear to be with the JVM but the application running in it. Using additional shared libraries, direct memory and memory mapped files can increase the amount of memory used.

Given you can buy 16 GB for around $100, do you know this is actually a problem?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文