2013-03-27 6 views
15

enter image description hereMapped Buffer Pool/Direct Buffer Poolとはどのようにしてサイズを増やすのですか?

VisualVMののスクリーンショットは、私は(Scalaで書かれた)IO集中JVMプログラムを実行したときに、ヒープサイズが4GBであったとわずか2 GBが使用中であった取りました。 JVMプログラムは、メモリマップファイルを使用します。

"マップされたバッファプール"と "直接バッファプール"の意味は何ですか?

これらのプールは非常に満杯に見えます。 JVMプログラムはメモリマップファイルを使用しているため、プールが大きければパフォーマンスが向上しますか?もしそうなら、サイズを増やす方法は?

マップされたすべてのファイルのサイズは約1.1GBです。

答えて

36

ダイレクトバッファー

direct bufferは、典型的には、それがソケットから受信するかのようにOSがデータを書き込む場所として、例えば、OS I/OサブシステムへのJavaのインタフェースに使用されるメモリのチャンクでありますディスクであり、Javaから直接読み取ることができます。

OSとのバッファの共有は、OSからJavaのメモリモデルにデータをコピーするという従来のアプローチよりもはるかに効率的です。このため、データはガベージコレクションの対象となり、データの再コピーなどの非効率性がありますエデンから生存者 - >テニュア - >から永続的な世代に移行します。

このスクリーンショットには、16KBのダイレクトバッファーのバッファが1つしかありません。 Javaはこのプールを必要に応じて拡張するので、青い領域がブロックの最上部にあるという事実は、今までが割り当てられたバッファメモリがすべてであるという文にすぎません。私はこれを問題として見ていない。

マップされ、バッファプール

マッピングされたバッファ・プールは、そのFileChannelインスタンスは、Javaによって使用されるすべてのメモリです。

各FileChannelインスタンスには、OSと共有されるバッファがあります(すべての効率の点で直接バッファに似ています)。メモリは本質的に、ファイルの一部分上のインRAMウィンドウである。モード(読み込み、書き込み、またはその両方)に応じて、Javaはファイルの内容を直接読み取ったり変更したりすることができ、OSは直接データをディスクに供給したり、変更したデータをディスクに書き出すことができます。

OSのシャットダウン時など、OSがこのバッファをディスクに直接フラッシュすることが可能で、OSがファイルのその部分を他のプロセスからロックすることができますコンピューター。

このスクリーンショットは、12 FileChannelオブジェクトで約680MB使用していることを示しています。ここでも、JavaはScalaがさらに必要とする(これはJVMがOSから追加のメモリを得ることができる)ため、680MBがすべて使用されているということは重要ではありません。彼らのサイズを考えれば、プログラムがすでにこれらのバッファを有効に使うように最適化されているように思えます。マッピングされたバッファプールのサイズ

のJavaを増やす

はのFileChannelバッファのガベージコレクション空間の外のメモリを割り当てます。つまり、-Xmxのような通常のヒープサイズパラメータは重要ではありません。

mapメソッドでバッファのサイズが設定されています。これを変更すると、Scalaプログラムが変更されます

バッファが10〜100sのKBのスレッシュホールドサイズに達したら、FileChannelバッファサイズを大きくするかどうかは、プログラムがバッファをどのように使用するかによって異なります:

  • ません:ファイルが最後の最後まで正確に一度読まれている場合:ほぼすべての時間のいずれかのディスクまたは処理アルゴリズムたぶん
  • を待っている:もし、しかし、アルゴリズム頻繁に部分を再訪するファイルを何度もスキャンし、
    • 変更またはファイルを書く場合は、より多くを統合することができ、より大きなバッファは、単一のフラッシュに書き込む:サイズngをすることはパフォーマンスが向上する場合があります。
    • ファイルを読み込んだ場合、オペレーティングシステムはすでにファイル(ディスクキャッシュ)をキャッシュしている可能性があります。 JVMのサイズを劇的に大きくすると、実効ディスク・キャッシュ・サイズを小さくすることによってパフォーマンスが低下する可能性があります。
    • アプリケーションには、キャッシュに独自の論理レコード・ポインタを実装するなどの利点があります。

(JProfilerをとYourKitは、この得意な)アプリケーションプロファイリングを試してみて、I/O待機を探します。ファイルI/Oは実際には問題ではないかもしれません - premature optimizationの犠牲者ではないでしょう。 I/O待機が合計経過時間の重要な部分である場合、それもあることに注意してください

さらなる情報は

https://blogs.oracle.com/alanb/entry/monitoring_direct_buffers

大きいバッファサイズを試してみる価値があるかもしれませんJVM上で、FileChannelがメモリを解放していないとのバグが報告されました。詳細はPrevent OutOfMemory when using java.nio.MappedByteBuffer

+0

これまでに私がstackoverflowで受け取った最も素晴らしい答えです。どうもありがとうございます! –

+1

@HowardGuo:ようこそ。:) –

関連する問題