「オンヒープ」と「オフヒープ」の違い


回答:


169

ヒープ上のストアは、Javaヒープに存在する(GCの対象にもなる)オブジェクトを指します。一方、オフヒープストアとは、EHCacheによって管理されているが、ヒープの外部に格納されている(GCの対象ではない)(シリアル化された)オブジェクトを指します。オフヒープストアは引き続きメモリ内で管理されるため、オンヒープストアよりも若干低速ですが、ディスクストアよりも高速です。

オフヒープストアの管理と使用に関連する内部の詳細は、質問に投稿されたリンクではあまり明らかではないため、オフディスクの管理に使用されるTerracotta BigMemoryの詳細を確認することをお勧めしますお店。BigMemory(オフヒープストア)は、数メガバイトまたはギガバイトのヒープ上のGCのオーバーヘッドを回避するために使用されます。BigMemoryは、他のネイティブJavaオブジェクトとは異なり、GCの影響を受けない直接ByteBufferを介して、JVMプロセスのメモリアドレス空間を使用します。


18
さらなる調査のために直接ByteBufferに言及するための+1;)
最大

3
直接ByteBufferは、アンマネージメモリへのアクセスを提供しますが、それ自体が(それらが指すデータとは対照的に)GCの対象になります。ダイレクトByteBuffer(MMapの種類ではなくByteBuffer.allocateDirectの種類)がGCによって収集され、収集されるとDeallocaterがトリガーされ、アンマネージメモリも効果的に収集されるため、これは重要です。
Nitsan Wakart 2015

Unsafeを使用してオブジェクトを割り当てると、Onheap / DirectByteBuffers / ByteBuffersよりも読み取りと書き込みのパフォーマンスが大幅に向上するように見えます。ashkrit.blogspot.com/2013/07/…–
Joe C、

98

http://code.google.com/p/fast-serialization/wiki/QuickStartHeapOffから

ヒープオフロードとは

通常、割り当てたすべての非一時オブジェクトは、Javaのガベージコレクターによって管理されます。VMはガベージコレクションを行う適切なジョブを実行しますが、特定の時点で、VMはいわゆる「フルGC」を実行する必要があります。フルGCでは、割り当てられたヒープ全体をスキャンします。つまり、GCの一時停止/スローダウンは、アプリケーションのヒープサイズに比例します。したがって、「メモリは安い」と言っている人を信用しないでください。Javaのメモリを消費すると、パフォーマンスが低下します。さらに、1 Gbを超えるヒープサイズを使用すると、顕著な一時停止が発生する場合があります。ほぼリアルタイムで何かが起こっている場合、クラスターまたはグリッドでJavaプロセスが応答しなくなり、クラスターから削除される可能性があります。

ただし、今日のサーバーアプリケーション(頻繁に肥大化したフレームワーク上に構築される;-))では、4Gbをはるかに超えるヒープを簡単に必要とします。

これらのメモリ要件に対する1つの解決策は、オブジェクトの一部を非Javaヒープ(OSから直接割り当てられる)に「オフロード」することです。幸い、java.nioは、「管理されていない」メモリチャンク(メモリマップファイルも含む)を直接割り当て/読み取りおよび書き込みするクラスを提供します。

したがって、大量の「アンマネージド」メモリを割り当て、これを使用してオブジェクトをそこに保存できます。任意のオブジェクトをアンマネージメモリに保存するための最も実行可能なソリューションは、シリアル化の使用です。これは、アプリケーションがオブジェクトをオフヒープメモリにシリアル化し、後で逆シリアル化を使用してオブジェクトを読み取ることができることを意味します。

Java VMによって管理されるヒープサイズを小さく保つことができるので、GCの一時停止はミリ秒単位で、誰もが満足して仕事が完了します。

このようなオフヒープバッファーのパフォーマンスは、主にシリアル化実装のパフォーマンスに依存することは明らかです。朗報:なんらかの理由でFSTのシリアル化はかなり高速です:-)。

使用シナリオの例:

  • サーバーアプリケーションのセッションキャッシュ。メモリマップファイルを使用して、ギガバイトの(非アクティブ)ユーザーセッションを格納します。ユーザーがアプリケーションにログインすると、データベースを扱う必要なく、ユーザー関連のデータにすばやくアクセスできます。
  • 計算結果(クエリ、htmlページなど)のキャッシュ(計算が結果オブジェクトの逆シリアル化よりも遅い場合にのみ適用可能)
  • メモリマップファイルを使用した非常にシンプルで高速な永続化

編集:シナリオによっては、より大きなヒープをサポートするために、ConcurrentMarkAndSweepやG1などのより洗練されたガベージコレクションアルゴリズムを選択する場合があります(ただし、これには16GBヒープを超える制限もあります)。「一時停止のない」GC(Azul)が改善された商用JVMもあります。


4
「大量の「管理されていない」メモリを割り当て、これを使用してオブジェクトをそこに保存する」-オブジェクトをオフヒープに保存することはできません。プリミティブを保存したり、好きなライブラリにラップしたりできますが、これらはオブジェクトではありません。オフヒープに配置するデータにはオブジェクトヘッダーがなく、同期することも、他のオブジェクトの参照フィールドで参照することもできません。
Nitsan Wakart 2015

41

ヒープは、動的に割り当てられたオブジェクトが存在するメモリ内の場所です。使用した場合new、それはヒープ上にあります。これは、関数スタックが存在するスタックスペースとは対照的です。ローカル変数がある場合、その参照はスタックにあります。Javaのヒープはガベージコレクションの対象であり、オブジェクトは直接使用できます。

EHCacheのオフヒープストレージは、通常のオブジェクトをヒープから取り出してシリアル化し、EHCacheが管理するメモリのチャンクにバイトとして格納します。ディスクに保存するようなものですが、それでもRAMにあります。この状態では、オブジェクトを直接使用することはできません。最初にデシリアライズする必要があります。また、ガベージコレクションの対象ではありません。


それは単にヒープに残っているのではなく、シリアル化された形式ではありませんか?
ペーチェリエ

1
どうすればより効率的になりますか?
パセリエ

2
方法はたくさんあります。オブジェクトはもはやメインのJavaヒープ上にないので、ガベージコレクターの時間を無駄にすることはありません。JVMのヒープを断片化せず、他の使用頻度の高いオブジェクトのためにスペースを解放します。また、これらはシリアル化されており、近い将来必要とされない可能性が高いため、圧縮したり、必要に応じて移動したり、ディスクにページアウトしたりすることもできます。
アダム

1
Hotspotでは、GCの一時停止時間はヒープサイズに直接依存します。BigMemoryは、ヒープの代わりにRAMを使用してこのトレードオフを提供し、GCの一時停止を最小限に抑え、ディスクアクセスのIOコストを回避します。
Chander Shivdasani、2012


1

JVMは、ヒープ外メモリについて何も認識していません。Ehcacheは、ディスク上のキャッシュとメモリ内のキャッシュを実装します。


1

100%ではありません。ただし、ヒープはオブジェクトまたは割り当てられたスペースのセット(RAM上)であり、Java自体またはehcache自体の機能である可能性が高いコードの機能に組み込まれており、オフヒープRamは独自のシステムとして存在します。上手; ただし、これは組織化されていないため、1倍遅くなるように聞こえます。つまり、ヒープ(RAMの1つの長いスペースのセット)を使用しない可能性があり、代わりに異なるアドレススペースを使用するため、効率が若干低下する可能性があります。

もちろん、次に下の階層はハードドライブの容量そのものです。

私はehcacheを使用しないので、あなたは私を信頼したくないかもしれませんが、それは私が彼らのドキュメントから収集したものです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.