私はいつも、Java のガベージ コレクターが実行するのではなく、必要に応じてアクティブ化するのはなぜなのか疑問に思っていました。
if(obj.refCount == 0)
{
delete obj;
}
私が見落としていた、Java がそれを行う方法に大きな利点はありますか?
ありがとう
私はいつも、Java のガベージ コレクターが実行するのではなく、必要に応じてアクティブ化するのはなぜなのか疑問に思っていました。
if(obj.refCount == 0)
{
delete obj;
}
私が見落としていた、Java がそれを行う方法に大きな利点はありますか?
ありがとう
各JVMは異なりますが、HotSpot JVMは、ガベージコレクションの手段として主に参照カウントに依存していません。参照カウントには、実装が簡単であるという利点がありますが、本質的にエラーが発生しやすくなります。特に、参照サイクル(サイクル内ですべてが相互に参照するオブジェクトのセット)がある場合、それらはすべてゼロ以外の参照カウントを持っているため、参照カウントはそれらのオブジェクトを正しく再利用しません。これにより、補助的なガベージコレクターを使用する必要があり、速度が低下する傾向があります(Mozilla Firefoxにはこの正確な問題があり、その解決策は、コードの可読性を大幅に犠牲にしてガベージコレクターを追加することでした)。これが、たとえば、C ++のような言語では、shared_ptr
参照カウントを使用するweak_ptr
sと参照サイクルを使用しないsの組み合わせを持つ傾向がある理由です。
さらに、参照カウントを各オブジェクトに関連付けると、参照カウントの調整に伴う余分な簿記のために、参照を割り当てるコストが通常よりも高くなります(マルチスレッドが存在する場合にのみ悪化します)。さらに、参照カウントを使用すると、特定のタイプの高速メモリアロケータを使用できなくなります。これは問題になる可能性があります。また、オブジェクトが密集しているのではなくメモリ全体に分散しているため、単純な形でヒープの断片化が発生する傾向があり、割り当て時間が短縮され、局所性が低下します。
HotSpot JVMは、さまざまな手法を使用してガベージコレクションを実行しますが、その主要なガベージコレクターはストップアンドコピーコレクターと呼ばれます。このコレクターは、メモリ内でオブジェクトを隣り合わせに連続して割り当てることで機能し、新しいオブジェクトの非常に高速な(1つまたは2つのアセンブリ命令)割り当てを可能にします。スペースがなくなると、すべての新しいオブジェクトが同時にGCされます。これにより、通常、構築された新しいオブジェクトのほとんどが削除されます。その結果、GCは通常の参照カウントの実装よりもはるかに高速であり、最終的には局所性とパフォーマンスが向上します。
ガベージコレクションの手法の比較と、HotSpotのGCの動作の概要については、昨年の夏に教えたコンパイラコースのこれらの講義スライドを確認してください。また、アプリケーションごとにコレクターを調整する方法など、ガベージコレクターの動作について詳しく説明しているHotSpotガベージコレクションのホワイトペーパーも参照してください。
お役に立てれば!
参照カウントには次の制限があります。
参照カウントに基づいて厳密に機能しないためです。
アプリケーションの「ルート」から到達できなくなった循環参照を検討してください。
例えば:
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、その他多数) には、これに対するソリューションがあり、説明した方法と同様に機能します。
strong
ARCを使用すると、次のようなキーワードで参照に注釈を付ける必要がありweak
、これらの参照を処理する方法(および循環参照を回避する)をARCに知らせる必要があります... -of-time コンパイル プロセス中に実行され、特定のランタイム自体は必要ありません) したがって、説明した方法と同じように実行できますが、Java の一部の機能では機能しません。また、COM はあなたが説明した方法と似たように機能すると思いますが、開発者側である程度の考慮が必要です。
実際、「単純な」参照カウント方式は、アプリケーション開発者が (循環参照を避けるために) ある程度考えなければ実行できません。
copying collector
これは、Javaのガベージコレクターが「youggenerations」オブジェクトと「tenuregenerations」オブジェクトに
基づいているためmark and sweep
です。
リソース: http: //java.sun.com/docs/hotspot/gc1.4.2/faq.html
最新の JVM のガベージ コレクターは参照カウントを追跡しなくなったためです。このアルゴリズムは GC がどのように機能するかを教えるために使用されますが、リソースを消費し、エラーが発生しやすいものでした (循環依存など)。