誰かがARCの仕組みを簡単に説明してもらえますか?ガベージコレクションとは違うことは知っていますが、正確にどのように機能するのか疑問に思っていました。
また、ARCがパフォーマンスを妨げることなくGCが行うことを行う場合、なぜJavaはGCを使用するのでしょうか。なぜARCも使用しないのですか?
誰かがARCの仕組みを簡単に説明してもらえますか?ガベージコレクションとは違うことは知っていますが、正確にどのように機能するのか疑問に思っていました。
また、ARCがパフォーマンスを妨げることなくGCが行うことを行う場合、なぜJavaはGCを使用するのでしょうか。なぜARCも使用しないのですか?
Objective-Cに来るすべての新しい開発者は、オブジェクトを保持、解放、および自動解放するタイミングの厳格なルールを学ぶ必要があります。これらのルールは、メソッドから返されるオブジェクトの保持カウントを暗示する命名規則も指定します。これらのルールを心に留めて一貫して適用すると、Objective-Cのメモリ管理は第二の性質になりますが、最も経験豊富なCocoa開発者でさえ時々失敗します。
Clang Static Analyzerを使用して、LLVM開発者は、これらのルールが十分に信頼できるため、コードがたどるパス内のメモリリークとオーバーリリースを指摘するツールを構築できることに気付きました。
自動参照カウント(ARC)は、次の論理的なステップです。コンパイラがオブジェクトを保持および解放する場所を認識できる場合は、そのコードをコンパイラに挿入してもらいませんか?厳格で反復的なタスクは、コンパイラーとその兄弟が得意とするものです。人間は物事を忘れて間違いを犯しますが、コンピューターははるかに一貫性があります。
ただし、これによって、これらのプラットフォームでのメモリ管理について心配する必要が完全になくなるわけではありません。ここでの私の回答では、注意すべき主要な問題(保持サイクル)について説明します。これには、弱いポインターをマークするために少し考える必要がある場合があります。ただし、ARCで得ているものと比較すると、それはマイナーです。
手動のメモリ管理やガベージコレクションと比較すると、ARCは、保持/解放コードを記述する必要性を排除することで、両方の長所を提供しますが、ガベージコレクション環境で見られる停止および鋸歯状のメモリプロファイルはありません。ガベージコレクションがこれに勝る唯一の利点は、保持サイクルを処理できることと、アトミックプロパティの割り当てが安価であるという事実です(ここで説明します)。既存のMacGCコードをすべてARC実装に置き換えていることはわかっています。
これを他の言語に拡張できるかどうかについては、Objective-Cの参照カウントシステムを対象としているようです。これをJavaや他の言語に適用するのは難しいかもしれませんが、そこで決定的なステートメントを作成するための低レベルのコンパイラの詳細については十分にわかりません。AppleがLLVMでこの取り組みを推進していることを考えると、他の当事者がこれに独自の重要なリソースをコミットしない限り、Objective-Cが最初になります。
このショックを受けた開発者の発表はWWDCで行われたため、人々はこのようなことができることに気づいていませんでした。時間の経過とともに他のプラットフォームに表示される可能性がありますが、現時点ではLLVMとObjective-C専用です。
ARCは、コンパイラが保持/解放をいつ呼び出すかを判断して、古い保持/解放(MRC)を再生するだけです。GCシステムよりもパフォーマンスが高く、ピークメモリ使用量が少なく、パフォーマンスが予測しやすい傾向があります。
一方、一部のタイプのデータ構造はARC(またはMRC)では不可能ですが、GCはそれらを処理できます。
例として、nodeという名前のクラスがあり、nodeに子のNSArrayがあり、その親への単一の参照がGCで「正しく機能する」場合。ARC(および手動参照カウント)では、問題が発生します。任意のノードは、その子およびその親から参照されます。
好き:
A -> [B1, B2, B3]
B1 -> A, B2 -> A, B3 -> A
Aを使用している間はすべて問題ありません(たとえば、ローカル変数を介して)。
それ(およびB1 / B2 / B3)が完了すると、GCシステムは最終的に、スタックおよびCPUレジスターから始めて見つけることができるすべてのものを調べることを決定します。A、B1、B2、B3は検出されないため、それらをファイナライズし、メモリを他のオブジェクトにリサイクルします。
ARCまたはMRCを使用し、Aで終了すると、参照カウントは3になり(B1、B2、およびB3はすべてそれを参照します)、B1 / B2 / B3はすべて参照カウントが1になります(AのNSArrayは1つの参照を保持します。各)。したがって、これらのオブジェクトは、何も使用できない場合でも、ライブのままです。
一般的な解決策は、これらの参照の1つを弱くする必要があると判断することです(参照数には寄与しません)。これは、Aを介してのみB1 / B2 / B3を参照する場合など、一部の使用パターンでは機能します。ただし、他のパターンでは失敗します。たとえば、時々B1を保持し、親ポインタを介して上に戻ってAを見つけることを期待する場合。B1のみを保持する場合、弱い参照を使用すると、Aは蒸発し、B2、およびB3を取得できます。それと。
これが問題にならない場合もありますが、データの複雑な構造を操作するための非常に便利で自然な方法のいくつかは、ARC/MRCで使用するのが非常に困難です。
したがって、ARCはGCが対象とするのと同じ種類の問題を対象としています。ただし、ARCはGCよりも限定された使用パターンのセットで動作するため、GC言語(Javaなど)を使用してARCのようなものを移植すると、一部のプログラムは動作しなくなります(または、少なくとも大量の放棄されたメモリが生成されます) 、および深刻なスワッピングの問題を引き起こしたり、メモリまたはスワップスペースを使い果たしたりする可能性があります)。
また、ARCはパフォーマンス(またはおそらく予測可能性)をより優先し、GCは一般的なソリューションであることをより優先すると言うこともできます。その結果、GCのCPU /メモリ需要は予測できず、(通常は)ARCよりもパフォーマンスが低くなりますが、任意の使用パターンを処理できます。ARCは、多くの一般的な使用パターンではるかにうまく機能しますが、いくつかの(有効な!)使用パターンでは、転倒して消滅します。
魔法
しかし、より具体的には、ARCは、コードで行うことを正確に実行することによって機能します(ただし、特定の小さな違いがあります)。ARCはコンパイル時テクノロジであり、実行時でパフォーマンスに悪影響を与えるGCとは異なります。ARCはオブジェクトへの参照を追跡し、通常のルールに従って保持/解放/自動解放メソッドを合成します。このため、ARCは、純粋に慣例のために自動解放プールにそれらをスローするのではなく、不要になったときにすぐに解放することもできます。
その他のいくつかの改善には、弱参照のゼロ化、ヒープへのブロックの自動コピー、全面的な高速化(自動解放プールの場合は6倍!)が含まれます。
これらすべてがどのように機能するかについてのより詳細な議論は、ARCのLLVMドキュメントにあります。
ガベージコレクションとは大きく異なります。別の行でオブジェクトがリークしている可能性があることを示す警告を見たことがありますか?これらのステートメントは、オブジェクトを割り当てた行を示しています。これはさらに一歩進んだものであり、ほとんどのプログラマーよりもほぼ100%の確率で、適切な場所にretain
/ステートメントを挿入できるようになりました。release
時折、あなたがそれを手伝う必要がある保持されたオブジェクトのいくつかの奇妙なインスタンスがあります。
Appleデベロッパのドキュメントで非常によく説明されています。「ARCの仕組み」を読む
インスタンスがまだ必要なときに消えないようにするために、ARCは、各クラスインスタンスを現在参照しているプロパティ、定数、および変数の数を追跡します。そのインスタンスへのアクティブな参照が少なくとも1つ存在する限り、ARCはインスタンスの割り当てを解除しません。
インスタンスがまだ必要なときに消えないようにするために、ARCは、各クラスインスタンスを現在参照しているプロパティ、定数、および変数の数を追跡します。そのインスタンスへのアクティブな参照が少なくとも1つ存在する限り、ARCはインスタンスの割り当てを解除しません。
相違を知るため。ガベージコレクションとARCの間:これを読む
ARCは、オブジェクトの自動メモリ管理を提供するコンパイラ機能です。
retain, release
、、をいつ使用するかを覚えておく必要はありませんがautorelease
、ARCはオブジェクトの存続期間の要件を評価し、コンパイル時に適切なメモリ管理呼び出しを自動的に挿入します。コンパイラは、適切なdeallocメソッドも生成します。
コンパイラはコンパイル時に必要な呼び出しを挿入しretain/release
ますが、これらの呼び出しは他のコードと同じように実行時に実行されます。
次の図は、ARCがどのように機能するかをよりよく理解するのに役立ちます。
iOS開発に不慣れで、Objective Cの作業経験がない人。メモリ管理の理解を深めるには、Appleの高度なメモリ管理プログラミングガイドのドキュメントを参照してください。