誰かがARCのしくみを簡単に説明できますか?ガベージコレクションとは違うことは知っていますが、どういう仕組みになっているのか正確に疑問に思っていました。
また、ARCがパフォーマンスを妨げることなくGCを実行する場合、JavaはなぜGCを使用するのでしょうか。なぜARCも使用しないのですか?
誰かがARCのしくみを簡単に説明できますか?ガベージコレクションとは違うことは知っていますが、どういう仕組みになっているのか正確に疑問に思っていました。
また、ARCがパフォーマンスを妨げることなくGCを実行する場合、JavaはなぜGCを使用するのでしょうか。なぜARCも使用しないのですか?
回答:
Objective-Cに参加するすべての新しい開発者は、オブジェクトを保持、解放、および自動解放するときの厳格なルールを学ぶ必要があります。これらのルールは、メソッドから返されたオブジェクトの保持カウントを意味する命名規則も指定しています。Objective-Cでのメモリ管理は、これらのルールを真摯に受け止めて一貫して適用すると第2の性質になりますが、経験豊富なCocoa開発者でさえ時々失敗します。
Clang Static Analyzerを使用して、LLVM開発者は、これらのルールが十分に信頼できるため、コードがたどるパス内のメモリリークとオーバーリリースを指摘するツールを構築できることに気付きました。
自動参照カウント(ARC)は次の論理的なステップです。オブジェクトを保持および解放する場所をコンパイラーが認識できる場合は、そのコードを挿入してはどうですか。厳格で反復的なタスクは、コンパイラとその兄弟が得意とするものです。人間は物事を忘れて間違いを犯しますが、コンピュータははるかに一貫しています。
ただし、これらのプラットフォームでのメモリ管理について心配する必要が完全になくなるわけではありません。私はここで私の答えで(サイクルを維持する)に注意する主要な問題について説明します。これは、弱いポインタをマークするためにあなたの側で少し考える必要があるかもしれません。ただし、ARCで得られるものと比較すると、それはマイナーです。
手動のメモリ管理やガベージコレクションと比較すると、ARCは、保持/解放コードを記述する必要をなくし、ガベージコレクション環境で見られる停止および鋸歯状のメモリプロファイルがないため、両方の利点を提供します。ガベージコレクションがこれより優れている唯一の利点は、保持サイクルを処理できることと、アトミックプロパティの割り当てが安価であることです(ここで説明します)。既存のMac GCコードをすべてARC実装に置き換えていることを知っています。
これを他の言語に拡張できるかどうかについては、Objective-Cの参照カウントシステムを対象としています。これをJavaや他の言語に適用するのは難しいかもしれませんが、低レベルコンパイラの詳細について十分な知識がないので、そこに決定的な声明を出すことはできません。アップルが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で終了すると、refcountは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は、多くの一般的な使用パターンで非常によく機能しますが、いくつかの(有効な!)使用パターンでは、フォールバックして終了します。
foo = nil
。
マジック
しかし、より具体的には、ARCは、コードで行うのとまったく同じことを実行します(特定の小さな違いがあります)。ARCはコンパイル時テクノロジーであり、ランタイムでありパフォーマンスに悪影響を与えるGCとは異なります。ARCはオブジェクトへの参照を追跡し、通常のルールに従って保持/解放/自動解放メソッドを合成します。このため、ARCは、純粋に慣例のために自動解放プールに投入するのではなく、不要になったものをすぐに解放することもできます。
その他のいくつかの改善には、弱参照のゼロ化、ヒープへのブロックの自動コピー、ボード全体の高速化(自動解放プールの場合は6倍!)が含まれます。
これがどのように機能するかについてのより詳細な議論は、ARCのLLVM Docsにあります。
ガベージコレクションとは大きく異なります。別の行でオブジェクトをリークしている可能性があることを通知する警告を見ましたか?これらのステートメントは、オブジェクトを割り当てた行を教えてくれます。これはさらに一歩進んだものであり、ほとんどのプログラマよりも適切な場所にretain
/ release
ステートメントを挿入できるようになりました。ほぼ100%の時間です。ときどき、保持するオブジェクトの奇妙なインスタンスがあり、それを支援する必要があります。
Apple開発者のドキュメントで非常によく説明されています。「ARCの仕組み」を読む
必要なときにインスタンスが消えないようにするために、ARCは、各クラスインスタンスを現在参照しているプロパティ、定数、変数の数を追跡します。インスタンスへのアクティブな参照が少なくとも1つ存在する限り、ARCはインスタンスの割り当てを解除しません。
必要なときにインスタンスが消えないようにするために、ARCは、各クラスインスタンスを現在参照しているプロパティ、定数、変数の数を追跡します。インスタンスへのアクティブな参照が少なくとも1つ存在する限り、ARCはインスタンスの割り当てを解除しません。
違いを知ること。ガベージコレクションとARCの間:これを読む
ARCは、オブジェクトの自動メモリ管理を提供するコンパイラ機能です。
retain, release
、およびをいつ使用するかを覚える必要はなくautorelease
、ARCはオブジェクトの有効期間の要件を評価し、コンパイル時に適切なメモリ管理呼び出しを自動的に挿入します。コンパイラーは、適切なdeallocメソッドも生成します。
コンパイラーretain/release
はコンパイル時に必要な呼び出しを挿入しますが、これらの呼び出しは他のコードと同様に実行時に実行されます。
次の図は、ARCがどのように機能するかを理解するのに役立ちます。
iOS開発の初心者で、Objective Cの実務経験がない方。メモリ管理の詳細については、Appleのドキュメント 『Advanced Memory Management Programming Guide』を参照してください。