15

Java 仮想マシンはメモリ内のオブジェクトを移動しますか? もしそうなら、移動したオブジェクトへの参照の更新をどのように処理しますか?

オブジェクトを分散方式 (つまり、複数のサーバーにまたがる) で保存するというアイデアを検討しているので質問しますが、効率上の理由からサーバー間でオブジェクトを移動する機能が必要です。オブジェクトは、リモートサーバー上のオブジェクトであっても、相互へのポインターを含むことができる必要があります。移動したオブジェクトへの参照を更新する最善の方法を考えようとしています。

これまでのところ、私の2つのアイデアは次のとおりです。

  1. オブジェクトが移動した場合に更新する、オブジェクトの存続期間中移動しない場所での参照間接化を維持します。しかし、これらの間接化はどのように管理されているのでしょうか?
  2. 各オブジェクトの逆参照のリストを保持して、オブジェクトが移動された場合に何を更新する必要があるかを把握します。もちろん、これによりパフォーマンスのオーバーヘッドが生じます。

これらのアプローチに関するフィードバックと、代替アプローチの提案に興味があります。

4

6 に答える 6

11

ヒープのウォーキングに関する上記のコメントを参照してください。

異なるGCは異なる方法でそれを行います。

通常、ヒープをウォークするときにコレクターをコピーしますが、ヒープ内のすべてのオブジェクトをウォークするわけではありません。むしろ、ヒープ内の LIVE オブジェクトをウォークします。つまり、「ルート」オブジェクトから到達できる場合、オブジェクトはライブです。

したがって、この段階では、古いヒープから新しいヒープにオブジェクトをコピーするため、とにかくすべてのライブ オブジェクトにアクセスする必要があります。ライブ オブジェクトのコピーが完了すると、古いヒープに残るのは、既にコピーされているオブジェクトか、ガベージだけです。その時点で、古いヒープは完全に破棄できます。

この種のコレクターの 2 つの主な利点は、コピー フェーズ中にヒープを圧縮することと、生きているオブジェクトのみをコピーすることです。これは多くのシステムにとって重要です。この種のコレクターを使用すると、オブジェクトの割り当てが非常に安価であり、文字通りヒープ ポインターをインクリメントすることとほとんど変わらないからです。GC が発生すると、「死んだ」オブジェクトはコピーされないため、コレクターの速度が低下することはありません。また、動的システムでは、長期にわたるガベージよりも、少量の一時的なガベージの方がはるかに多いことがわかります。

また、ライブ オブジェクト グラフをたどることで、GC がどのようにすべてのオブジェクトを「認識」し、コピー中に実行されるアドレス調整のためにそれらを追跡できるかを確認できます。

これは重要な問題であるため、GC の仕組みについて深く話すフォーラムではありませんが、それはコピー コレクターがどのように機能するかの基本です。

世代コピー GC は、「古い」オブジェクトを異なるヒープに配置し、それらは「新しい」ヒープよりも収集される頻度が低くなります。理論的には、長持ちするオブジェクトは古い世代に昇格し、収集される頻度が減り、全体的な GC パフォーマンスが向上するというものです。

于 2008-09-18T01:43:45.467 に答える
3

あなたが求めているキーワードは「コンパクトなガベージコレクター」です。JVMは1つを使用できます。つまり、オブジェクトを再配置できます。JVMのマニュアルを参照して、JVMがそうであるかどうかを確認し、JVMに影響を与えるコマンドラインオプションがあるかどうかを確認してください。

圧縮を説明するための概念的に最も簡単な方法は、ガベージコレクターがすべてのスレッドをフリーズし、オブジェクトを再配置し、ヒープとスタックでそのオブジェクトへのすべての参照を検索し、それらを新しいアドレスで更新すると想定することです。実際には、それよりも複雑です。パフォーマンス上の理由から、スレッドが停止した状態で完全なスイープを実行したくないため、可能な場合はいつでも、インクリメンタルガベージコレクターが圧縮の準備として機能します。

間接参照に興味がある場合は、Javaの弱い参照とソフト参照、およびさまざまなRPCシステムで使用されるリモート参照を調査することから始めることができます。

于 2008-09-18T00:40:29.643 に答える
3

あなたの要件についてもっと知りたいです。別の答えが示唆するように、テラコッタはまさにあなたが探しているものかもしれません.

しかし、Terracotta が提供するものと、あなたが求めているものとの間には微妙な違いがあります。

違いは、Terracotta はオブジェクトへの「リモート」参照を提供しないことです。実際、Terracotta を使用する場合、RMI、JMS などの「リモート」概念全体が完全に存在しません。

むしろ、Terracotta では、すべてのオブジェクトが大きな仮想ヒープに存在します。ノード 1、ノード 2、ノード 3、ノード 4 などのスレッドはすべて、仮想ヒープ内の任意のオブジェクトにアクセスできます。

学習する特別なプログラミングや特別な API はありません。「仮想」ヒープ内のオブジェクトは、ローカル ヒープ内のオブジェクトとまったく同じ動作をします。

つまり、Terracotta が提供するのは、単一の JVM のプログラミング モデルとまったく同じように動作する、複数の JVM のプログラミング モデルです。別々のノードのスレッドは、単一のノードのスレッドのように動作します。オブジェクトの変更、同期、待機、通知はすべて、スレッド間と同様にノード間でまったく同じように動作します。違いはありません。

さらに、それ以前のソリューションとは異なり、オブジェクト参照はノード間で維持されます。つまり、== を使用できます。これはすべて、「通常の」Java (POJO、同期、待機/通知など) を機能させるための基本的な要件である、クラスター全体で Java メモリ モデルを維持するための一部です (保持しない/保持できない場合は、どれも機能しません)。クラスタ全体のオブジェクト ID)。

したがって、要件をさらに絞り込むために、質問が戻ってきます。「リモート」ポインターはどのような目的で必要ですか?

于 2008-09-30T06:06:39.503 に答える
2

(実際には) ガベージ コレクション システムでは、オブジェクトをメモリ内で移動させて、オブジェクトをより高密度にパックし、断片化の問題を回避する必要があります。

あなたが見ているのは、非常に大きく複雑な主題です。既存のリモート オブジェクト スタイル API を読むことをお勧めします。

参照を追跡するためのソリューションは、分散システムに存在するすべての障害モードに対処する必要があるため、複雑になります。JVM は、ネットワーク スイッチに問題が発生したためにヒープの半分が表示されないことに突然気付くことを心配する必要はありません。

設計を掘り下げると、多くの場合、さまざまな障害ケースをどのように処理したいかによって決まると思います。

コメントへの対応:

あなたの質問は、分散された方法でオブジェクトを保存することについて語っています。これは、まさに .NET リモート処理と CORBA のアドレスです。確かに、どちらのテクノロジーもこれらのオブジェクトの移行をサポートしていません (AFAIK)。しかし、どちらも、分散オブジェクト システムの重要な部分であるオブジェクト アイデンティティの概念を幅広く扱っています。つまり、システムのさまざまな部分がどのオブジェクトについて話しているかをどのように認識するかです。

私は Java ガベージ コレクターの詳細にあまり精通していません。Java および .NET ガベージ コレクターは、アプリケーションへの影響を最小限に抑えて最大のパフォーマンスを実現するために、かなり複雑になっていると思います。

ただし、ガベージ コレクションの基本的な考え方は次のとおりです。

  • VM は、マネージド コードの実行をすべてのスレッドで停止します
  • 既知の「ルート」のセット (静的変数、すべてのスレッドのローカル変数) から到達可能性分析を実行します。見つかったオブジェクトごとに、オブジェクト内のすべての参照に従います。
  • 到達可能性分析によって識別されないオブジェクトはすべてガベージです。
  • まだ生きているオブジェクトは、メモリ内で下に移動して密集させることができます。これは、これらのオブジェクトへの参照も新しいアドレスで更新する必要があることを意味します。ガベージ コレクションがいつ発生するかを制御することにより、VM は、問題を引き起こす可能性のある「空中」(つまり、マシン レジスタに保持されている) のオブジェクト参照がないことを保証できます。
  • プロセスが完了すると、VM はスレッドの実行を再開します。

このプロセスの改良として、VM は世代別ガベージ コレクションを実行できます。この場合、オブジェクトの「経過時間」に基づいて個別のヒープが維持されます。オブジェクトはヒープ 0 で開始し、いくつかの GC に耐えた場合、ヒープ 1 に移行し、最終的にヒープ 2 に移行します (同様に - .NET は 3 世代のみをサポートします)。これの利点は、GC がヒープ 0 コレクションを非常に頻繁に実行できることであり、(ヒープ 2 に終わった) 長期間有効なオブジェクトがまだ生きている (ほぼ確実に生きている) ことを証明する作業を心配する必要がないことです。 .

同時実行ガベージ コレクションをサポートするための他の改良点と、GC がスケジュールされているときに実際にアンマネージ コードを実行しているスレッドに関する詳細があり、この領域がさらに複雑になります。

于 2008-09-18T00:27:15.820 に答える
1

terracotta や oracle の Java オブジェクト キャッシュ (以前の tangersol) のような分散キャッシュを探しているようです。

于 2008-09-18T03:24:05.020 に答える
0

深く掘り下げたい場合は、JBoss Cache アーキテクチャのドキュメントを参照して、そのソース コードの一部を参照として入手してください。

これはまさにあなたが説明したものではありませんが、非常によく似ています。

リンクはこちらです。

http://www.jboss.org/jbosscache/

これが役立つことを願っています。

于 2008-09-30T16:23:56.213 に答える