9

私はいつも、Java のガベージ コレクターが実行するのではなく、必要に応じてアクティブ化するのはなぜなのか疑問に思っていました。

if(obj.refCount == 0)
{
   delete  obj;
}

私が見落としていた、Java がそれを行う方法に大きな利点はありますか?

ありがとう

4

5 に答える 5

19

各JVMは異なりますが、HotSpot JVMは、ガベージコレクションの手段として主に参照カウントに依存していません。参照カウントには、実装が簡単であるという利点がありますが、本質的にエラーが発生しやすくなります。特に、参照サイクル(サイクル内ですべてが相互に参照するオブジェクトのセット)がある場合、それらはすべてゼロ以外の参照カウントを持っているため、参照カウントはそれらのオブジェクトを正しく再利用しません。これにより、補助的なガベージコレクターを使用する必要があり、速度が低下する傾向があります(Mozilla Firefoxにはこの正確な問題があり、その解決策は、コードの可読性を大幅に犠牲にしてガベージコレクターを追加することでした)。これが、たとえば、C ++のような言語では、shared_ptr参照カウントを使用するweak_ptrsと参照サイクルを使用しないsの組み合わせを持つ傾向がある理由です。

さらに、参照カウントを各オブジェクトに関連付けると、参照カウントの調整に伴う余分な簿記のために、参照を割り当てるコストが通常よりも高くなります(マルチスレッドが存在する場合にのみ悪化します)。さらに、参照カウントを使用すると、特定のタイプの高速メモリアロケータを使用できなくなります。これは問題になる可能性があります。また、オブジェクトが密集しているのではなくメモリ全体に分散しているため、単純な形でヒープの断片化が発生する傾向があり、割り当て時間が短縮され、局所性が低下します。

HotSpot JVMは、さまざまな手法を使用してガベージコレクションを実行しますが、その主要なガベージコレクターはストップアンドコピーコレクターと呼ばれます。このコレクターは、メモリ内でオブジェクトを隣り合わせに連続して割り当てることで機能し、新しいオブジェクトの非常に高速な(1つまたは2つのアセンブリ命令)割り当てを可能にします。スペースがなくなると、すべての新しいオブジェクトが同時にGCされます。これにより、通常、構築された新しいオブジェクトのほとんどが削除されます。その結果、GCは通常の参照カウントの実装よりもはるかに高速であり、最終的には局所性とパフォーマンスが向上します。

ガベージコレクションの手法の比較と、HotSpotのGCの動作の概要については、昨年の夏に教えたコンパイラコースのこれらの講義スライドを確認してください。また、アプリケーションごとにコレクターを調整する方法など、ガベージコレクターの動作について詳しく説明しているHotSpotガベージコレクションのホワイトペーパーも参照してください。

お役に立てれば!

于 2012-01-08T21:26:17.927 に答える
4

参照カウントには次の制限があります。

  • マルチスレッドのパフォーマンスには非常に悪いです(基本的に、オブジェクト参照のすべての割り当てを保護する必要があります)。
  • サイクルを自動的に解放することはできません
于 2012-01-08T21:25:27.473 に答える
2

参照カウントに基づいて厳密に機能しないためです。

アプリケーションの「ルート」から到達できなくなった循環参照を検討してください。

例えば:

APPへの参照がありますSOME_SCREEN

SOME_SCREENへの参照がありますSOME_CHILD

SOME_CHILDへの参照がありますSOME_SCREEN

への参照をAPP削除しSOME_SCREENます。

この場合、 にはSOME_SCREENまだ への参照がSOME_CHILDあり、SOME_CHILDまだ への参照がありSOME_SCREENます。したがって、この場合、あなたの例は機能しません。

現在、他の人 (ARC を使用する Apple、COM を使用する Microsoft、その他多数) には、これに対するソリューションがあり、説明した方法と同様に機能します。

strongARCを使用すると、次のようなキーワードで参照に注釈を付ける必要がありweak、これらの参照を処理する方法(および循環参照を回避する)をARCに知らせる必要があります... -of-time コンパイル プロセス中に実行され、特定のランタイム自体は必要ありません) したがって、説明した方法と同じように実行できますが、Java の一部の機能では機能しません。また、COM はあなたが説明した方法と似たように機能すると思いますが、開発者側である程度の考慮が必要です。

実際、「単純な」参照カウント方式は、アプリケーション開発者が (循環参照を避けるために) ある程度考えなければ実行できません。

于 2012-01-08T21:24:26.207 に答える
0

copying collectorこれは、Javaのガベージコレクターが「youggenerations」オブジェクトと「tenuregenerations」オブジェクトに 基づいているためmark and sweepです。

リソース: http: //java.sun.com/docs/hotspot/gc1.4.2/faq.html

于 2012-01-08T21:26:24.663 に答える
0

最新の JVM のガベージ コレクターは参照カウントを追跡しなくなったためです。このアルゴリズムは GC がどのように機能するかを教えるために使用されますが、リソースを消費し、エラーが発生しやすいものでした (循環依存など)。

于 2012-01-08T21:24:34.077 に答える