web-dev-qa-db-ja.com

高Java小さなプログラムでもメモリ使用量

私はJavaで書かれたシンプルなアプリケーションをいくつか持っていますが、そのうちの1つはウィジェットとして機能するように書かれています。驚いたのは、RAM小さなアプリケーションでさえどれだけ使用するかです。

プログラムのバグか、一般的なJava問題かどうかを確認するために、次のように書きました。

public class ram {
    public static void main(String[] args){
    while(true)System.out.print("Hello World");//while loop to give me time to check RAM usage
    }
}

次に、コンパイルしてJava ramで実行すると、次のRAM使用法が得られます。

The process Java (with pid 4489) is using approximately 43.3 MB of memory.
34460 KB    [heap]
7088 KB /usr/lib/jvm/Java-7-openjdk/jre/lib/AMD64/server/libjvm.so
1712 KB /usr/lib/jvm/Java-7-openjdk/jre/lib/rt.jar
136 KB  [stack:4495]
120 KB  /usr/lib/jvm/Java-7-openjdk/jre/lib/AMD64/libjava.so

これは高すぎませんか?特に34MBのヒープ。私のシステムはArchLinux x86_64とopenjdk-7です。

JVMで使用されるRAMの量を最小限に抑える方法はありますか?

編集:-Xmxフラグを使用してみましたが、これは私が得たものです(1281kは最初に使用できる最小サイズでした):

Java -Xmx1281k ram
The process Java (with pid 4987) is using approximately 27.6 MB of memory.
18388 KB    [heap]

比較のため、Python2は4.4MBを使用し、Monoは4.3MBを使用します。

25
Vivo

これとよく似た質問が頻繁に寄せられますが、満足のいく答えはまだわかりません。

私が最も頻繁に目にする答えは、「なぜあなたは気にするのですか」と怒っています。答えます。一部の人々は質問をすることに多くの思考と努力を費やし、質問する人は誰でも馬鹿げているように見えます。

一部の人々は、さまざまな種類のメモリについて長いダイアトリブでこの質問に答えますJavaが割り当てる、なぜそれを行うのか、そしてどのコマンドラインパラメータを調べる必要があるのか​​を説明します。 )

事実は、小さなユーティリティの場合Javaは、ほとんどのオペレーティングシステムのメモリを消費します。ユーティリティが小さいほど、それがより明白になります。Java開発者はこの事実に対処または無視するように長い間条件付けられてきました。

一見異常なメモリ使用の理由はたくさんあります。各スレッドは、そのスタックのために一定量のメモリを取得します。ガベージクリーンアップ、RMIなどのプログラムがどれほど単純であるかに関係なく、いくつかのスレッドが開始されます。Windows/ 64ビットでは、スレッドごとに1MBです。たくさんのクラスがデフォルトでロードされ、すべてのクラスがロードされます。裏では他にもたくさんのことが起こっていると思います。

Javaは、他の言語にはないトレードオフの選択をしました。ロード時間は、他のほとんどの言語よりも遅くなります。初期メモリ要件は高くなります。最も一般的に使用される文字列は、ほとんどの人が理解するよりも多くのメモリを消費します。他にも数え切れないほどあります。多くの状況でのメリットは実際に報われます。 Hello Worldのようなものは、これらの選択のコストを何よりも誇示します。簡単なマルチスレッディングやネイティブに近いパフォーマンスなどの利点は、Hello Worldにはまったく役立ちません。

残念ながら、単純なアプリケーションで使用されるメモリを最小限に抑えるためにできることは多くありません。前述のコマンドラインスイッチがあり、試行錯誤によって、報告された使用量が10〜15 MBのレベルまで減少する可能性がありますが、それらを選択するために費やしたこれらの選択と時間は、幅広い種類には適用できません。将来のアプリケーションの。次のアプリケーションでは、同じプロセスを再度実行する必要があります。 GUIインターフェースといくつかのロギングと別の一般的なライブラリを1つまたは2つ投入すると、ベースの数値は最大60 MBに達します。

あなたは何も悪いことをしていません。これは、Javaでの動作方法に過ぎません。あなたはそれになれるようになる。そのため、時々別の言語を選択しますが、それも問題ありません。

81
Steve Kallestad

これにはいくつかの理由があります。

  1. Javaランタイム自体はかなり複雑なプログラムです。Javaプログラム(javacからの出力)のバイトコードを取得する必要があります。それが実行されているシステムのマシンコード、そのためのオプティマイザ、デバッグ用のインターフェースなどがあります。
  2. プログラムはかなり小さいですが、Javaは依然として標準ライブラリから多くのクラスをロードします。これは 'Java -verbose:class ram'を使用して起動すると確認できます
  3. Javaはプログラムに大量のメモリを事前に割り当てます。実際にどれだけのメモリが必要になるかはわかりません。これは、特に-Xmxオプションによって制御されます。このようなメモリにはいくつかの種類があります。それらの詳細については、JDKのbinフォルダーに含まれているJConsoleツールを使用できます。詳細については Java.Sun.com を参照してください。 Javaで使用されるメモリ領域の概要も このスタックオーバーフローの質問)で提供されます
7
stmoebius