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

Java 如何减少Sun/Oracle JVM内部开销?,java,eclipse,memory,jvm,overhead,Java,Eclipse,Memory,Jvm,Overhead,这个问题是关于运行在Linux x86-64上的Sun Java JVM的。我试图弄明白为什么sunjvm占用了系统如此多的物理内存,即使我设置了堆和非堆限制 我运行的程序是Eclipse3.7,具有多个插件/功能。最常用的功能是PDT、EGit和Mylyn。我使用以下命令行开关启动Eclipse: -nosplash -vmargs -Xincgc -Xms64m -Xmx200m -XX:NewSize=8m -XX:PermSize=80m -XX:MaxPermSize=150m -XX

这个问题是关于运行在Linux x86-64上的Sun Java JVM的。我试图弄明白为什么sunjvm占用了系统如此多的物理内存,即使我设置了堆和非堆限制

我运行的程序是Eclipse3.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所需的内部开销

实际上,JVM为我当前的Eclipse进程占用544.6MB,由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程序也有类似的经验——也许我可以通过类似的调整来减少所有Java程序的开销

更新:发布问题后,我发现以前的帖子是这样的:
似乎我应该使用
pmap
来调查这个问题。

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


我认为在堆外的内存方面,没有任何机会降低eclipse环境的内存消耗。

eclipse是一个内存和cpu的消耗者。除了Java类库之外,所有低端GUI都由本机系统调用处理,因此您将有一个实质性的“本机”JNI库来执行附加到流程的低级X术语调用

Eclipse提供了数以百万计的有用特性和许多帮助程序来加速您的日常编程任务,但这并不意味着它是精益的。内存或资源的任何减少都可能导致明显的减速。这实际上取决于你对时间和电脑内存的重视程度


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

如果我运行以下程序

public static void main(String... args) throws InterruptedException {
    for (int i = 0; i < 60; i++) {
        System.out.println("waiting " + i);
        Thread.sleep(1000);
    }
}
使用的内存量为13.5 MB。大约有200 MB的共享库,占VSZ的大小。其余的可以在max heap、max perm gen中计算,并为线程堆栈等增加开销

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


考虑到你可以用大约100美元买到16GB,你知道这实际上是个问题吗?

你真的在使用Sun JVM吗?或者您正在使用当前的Oracle JVM?以下是您想要了解的内容:Sun JVM和Oracle JVM之间的区别是什么?我得到了以下信息:“$java-version”java version“1.6.0_26”java(TM)SE运行时环境(build1.6.0_26-b03)java热点(TM)64位服务器虚拟机(build20.1-b02,混合模式)@Mikko:最近的版本实际上是Oracle JVM。不久前,在Java 6u20发行版前后的某个时候,所有“Sun JVM”实际上都开始成为“Oracle JVM”。对于Java进程中不断增长的RSS大小,请看我没有使用Eclipse的任何“IDE”功能(对我来说,“IDE”意味着自动代码生成、自动构建等)。我正在使用Eclipse作为一个非常智能的文本编辑器,它具有智能ondemand代码完成支持、代码导航助手和集成的在线文档工具。在堆栈中添加Mylyn,最终的结果确实比emacs或vim更好。我同意“make”更适合于自动化构建,我还认为“gitgui”和“gitk”优于EGit/Eclipse支持。除了其他工具之外,使用Eclipse工具更好。当然,内存很便宜,但如果有一个简单的修复方法,我不愿意浪费200 MB的实际内存。目前我认为赫弗沃尔夫是对的,这是由SWT引起的。我以前没有意识到JVM不能监视或限制SWT内存的使用。如果您试图找出问题的原因,通常最好测试一个简单的配置以进行比较我更喜欢使用IntelliJ,它不使用SWT。(Netbeans也不例外)
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