3

この問題は、特にLinuxx86-64で実行されているSunJavaJVMに関するものです。ヒープ制限と非ヒープ制限を設定した場合でも、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に制限する必要があります(JConsoleでラベル付けされた「CMS永続生成」および「コードキャッシュ」)。論理的には、JVMは合計350MBに加えてJVMに必要な内部オーバーヘッドを必要とします。

実際には、Linux 2.6以降のカーネルによって予約されている実際の物理メモリページを計算するps_mem.py(http://www.pixelbeat.org/scripts/ps_mem.py )によって計算されるように、JVMは現在のEclipseプロセスに544.6MBを使用します。 。これは、35%または約200MBの内部SunJVMオーバーヘッドです。

このオーバーヘッドを減らす方法についてのヒントはありますか?

ここにいくつかの追加情報があります:

$ 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によると、このプロセスでは160MBのヒープと151MBの非ヒープが使用されています。

Eclipseを実行するために余分な200MBを使用する余裕がないと言っているわけではありませんが、この無駄を減らす方法がある場合は、カーネルブロックデバイスバッファーまたはファイルキャッシュにその200MBを使用したいと思います。さらに、私は他のJavaプログラムでも同様の経験を持っています。おそらく、同様の調整を行うことで、それらすべてのオーバーヘッドを減らすことができます。

更新:質問を投稿した後、SOへの以前の投稿を見つけました: ヒープなどのサイズが安定している場合でも、Sun JVMがRSSメモリをこれまで以上に消費し続けるのはなぜですか?pmap問題を調査するために 使用する必要があるようです。

4

3 に答える 3

3

Eclipse環境でメモリを大量に消費する理由は、SWTを使用しているためだと思います。SWTは、JVMのヒープの外にあるネイティブのグラフィックライブラリであり、状況を悪化させるために、Linuxでの実装は実際には最適化されていません。

ヒープ外のメモリに関して、Eclipse環境のメモリ消費を減らすチャンスは実際にはないと思います。

于 2011-10-18T10:31:53.473 に答える
1

EclipseはメモリとCPUを大量に消費します。Javaクラスライブラリに加えて、すべてのローエンドGUIはネイティブシステムコールによって処理されるため、プロセスにアタッチされた低レベルのXタームコールを実行するための実質的な「ネイティブ」JNIライブラリがあります。

Eclipseは、日々のプログラミングタスクをスピードアップするために、何百万もの便利な機能と多くのヘルパーを提供しますが、無駄がなく、そうではないことを意味します。メモリまたはリソースが減少すると、おそらく顕著な速度低下が発生します。それは本当にあなたがあなたの時間とあなたのコンピュータのメモリをどれだけ大切にするかに依存します。

あなたが無駄のない、平均的なgvimとmakeが必要な場合は無敵です。コードの完成、自動ビルドなどが必要な場合は、追加のリソースでこれを支払うことを期待する必要があります。

于 2011-10-18T10:32:37.673 に答える
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.5MBです。VSZサイズにカウントされる約200MBの共有ライブラリがあります。残りは、スレッドスタックのオーバーヘッドを伴う最大ヒープ、最大パーマ生成などでカウントできます。

問題はJVMにあるようには見えませんが、JVMで実行されているアプリケーションにあります。追加の共有ライブラリを使用すると、ダイレクトメモリおよびメモリマップトファイルにより、使用されるメモリの量を増やすことができます。

16GBを約$100で購入できるとすると、これが実際に問題になっていることをご存知ですか?

于 2011-10-18T13:02:45.677 に答える