スマートポインターが存在する場合にガベージコレクションを行う理由


67

最近では、非常に多くの言語がガベージコレクションされています。サードパーティによってC ++でも利用可能です。しかし、C ++にはRAIIとスマートポインターがあります。それでは、ガベージコレクションを使用する意味は何ですか?何か特別なことをしていますか?

また、C#などの他の言語では、すべての参照が仕様と実装によってスマートポインターとして扱われる場合(RAIIは別として)、ガベージコレクターの必要性はまだありますか?いいえの場合、なぜそうではないのですか?


1
この質問を聞いて理解したことの1つは、スマートポインターが自動割り当て解除を管理するためにRAIIを必要とすることです。
グルシャン

8
スマートポインターとは、GCにRAIIを使用することを意味します;)
ダリオ

へえ、c#にはRAIIですべての「ガベージコレクション」を処理するオプションが必要です。循環参照は、アプリケーションのシャットダウン時に検出できます。必要なのは、Program.cs-classが割り当て解除された後、どの割り当てがまだメモリに残っているかを確認することだけです。その後、循環参照をある種の週の参照に置き換えることができます。
AareP

回答:


67

それでは、ガベージコレクションを使用する意味は何ですか?

参照カウントのスマートポインターを意味すると仮定していますが、これらは(基本的な)ガベージコレクションの形式であることに注意してください。代わりに。

  • 精度。参照カウントだけではサイクルがリークするため、参照カウントのスマートポインターは、サイクルをキャッチするために他の手法を追加しない限り、一般にメモリをリークします。これらの手法が追加されると、参照カウントの単純さの利点はなくなりました。また、スコープベースの参照カウントとトレースGCは異なる時間に値を収集します。参照カウントはより早く収集され、トレースGCはより早く収集されることもあります。

  • スループット。スマートポインターは、特に参照カウントがアトミックにバンプされるマルチスレッドアプリケーションのコンテキストでは、ガーベッジコレクションの最も効率の悪い形式の1つです。これを軽減するために設計された高度な参照カウント手法がありますが、実稼働環境ではGCのトレースが依然として最適なアルゴリズムです。

  • レイテンシー。典型的なスマートポインターの実装では、デストラクタが雪崩を起こし、無制限の一時停止時間が発生します。ベーカーのトレッドミルなど、他の形式のガベージコレクションははるかにインクリメンタルであり、リアルタイムにすることもできます。


23
この答えがトップの答えになったとは信じられません。それは、C ++スマートポインタの完全な理解不足を示しており、現実とあまりにも同期していないと主張しているため、単純にばかげています。まず、適切に設計されたC ++コードで最も支配的なスマートポインターは、共有ポインターではなく一意のポインターです。en.cppreference.com/w/cpp/memory/unique_ptr 第2に、スマートポインターに対する非決定的ガベージコレクションの「パフォーマンス」の利点とリアルタイムの利点を実際に主張しているとは信じられません。
user1703394

4
@ user1703394アンサーは共有ポインタを念頭に置いていたようです(正しいか間違っているか、OPが何を示唆しているのかよくわかりません)。
ネイサンクーパー

8
これらはすべてストローマンの引数であり、実際の質問を完全に無視するか、異なる種類のスマートポインターの実際の使用パターンを無視する場合にのみ有効です。問題はスマートポインターに関するものでした。はい、shared_ptrはスマートポインターであり、はい、shared_ptrは最も高価なスマートポインターですが、いいえ、パフォーマンスの引数を関連性のあるものに近いところに広範に使用するための実際の引数はありません。真剣に、この答えは参照カウントに関する質問に移されるべきです。良いスマートポインターの質問に対する参照カウントの答えは貧弱です。
user1703394

4
「スマートポインターはより広い概念ではありません」、真剣に?このステートメントが、これまでに行ったすべての有効な引数をどれだけ損なうかはわかりません。Rustの所有権とムーブのセマンティクスをご覧くださいkoerbitz.me/posts / ... C ++の歴史的な経験がある人は、C ++ 11 / C ++ 14がそのメモリモデルでスマートに改善されたという事実を逃すのは簡単です。ポインターと移動セマンティクスは、それらの前身とはまったく異なる獣です。Rustの仕組みをご覧ください。C++よりもクリーンで、新鮮な視点を提供します。
user1703394

6
@ user1703394:「デストラクタによる無制限の一時停止は、非メモリリソースに使用されるRAIIの不幸な特性です」いいえ、これはメモリ以外のリソースとは何の関係もありません。
ジョンハロップ

63

誰もこの角度からそれを見ていないので、私はあなたの質問を言い換えます:あなたが図書館でそれをすることができるなら、なぜ言語に何かを入れますか?特定の実装と構文の詳細を無視すると、GC /スマートポインターは基本的にその質問の特別なケースです。ライブラリに実装できるのに、言語自体でガベージコレクタを定義するのはなぜですか?

その質問にはいくつかの答えがあります。最も重要な最初の:

  1. すべてのコードがそれを使用して相互運用できることを確認します。これが、コードの再利用とコード共有がJava / C#/ Python / Rubyまで実際にうまくいかなかっ大きな理由だと思います。ライブラリは通信する必要があり、ライブラリが持つ唯一の信頼できる共有言語は、言語仕様自体(およびある程度、その標準ライブラリ)にあるものです。ライブラリをC ++で再利用しようとしたことがあるなら、おそらく標準のメモリセマンティクスによって引き起こされる恐ろしい痛みを経験したことはないでしょう。構造体をlibに渡したい。参照を渡しますか?ポインター?scoped_ptrsmart_ptr?所有権を渡しますか?それを示す方法はありますか?ライブラリを割り当てる必要がある場合はどうなりますか?アロケーターを与える必要がありますか?メモリ管理を言語の一部にしないことにより、C ++は各ライブラリペアに独自の特定の戦略をここでネゴシエートするように強制し、それらすべてに同意させるのは本当に困難です。GCはそれを完全な非発行にします。

  2. その周りの構文を設計できます。C ++はメモリ管理自体をカプセル化しないため、ユーザーレベルのコードですべての詳細を表現できるように、一連の構文フックを提供する必要があります。ポインター、参照const、、間接参照演算子、間接演算子、アドレスなどがあります。メモリ管理を言語自体にロールインする場合、それを中心に構文を設計できます。これらの演算子はすべて消え、言語はより簡潔でシンプルになります。

  3. 高い投資収益率が得られます。与えられたコードが生成する値は、それを使用する人の数で乗算されます。これは、ユーザー数が多いほど、ソフトウェアに費やす余裕ができることを意味します。機能を言語に移動すると、その言語のすべてのユーザーがその機能を使用します。これは、これらのユーザーのサブセットのみが使用するライブラリに割り当てるよりも多くの労力を割り当てることができることを意味します。これが、JavaやC#のような言語が絶対に一流のVMと非常に高品質のガベージコレクターを備えている理由です。これらの開発コストは、何百万人ものユーザーで償却されます。


素晴らしい答え!場合にのみ、私は...回以上upvote可能性
ディーン・ハーディング

10
ガベージコレクションは、実際にはC#言語自体ではなく、.NET Framework、特にCommon Language Runtime(CLR)に実装されていることに注意してください。
ロバートハーベイ

6
@RobertHarvey:言語によって実装されていませんが、言語の協力なしでは機能しません。たとえば、コンパイラーは、コード内のすべてのポイントで、ピン解除されたオブジェクトへの参照を保持するすべてのレジスターまたはスタックフレームオフセットの位置を指定する情報を含める必要があります。これは絶対的な例外なしの不変式であり、言語サポートなしでは維持できません。
supercat

GCが言語と必要なフレームワークをサポートすることの主な利点は、他の目的に割り当てられる可能性のあるメモリへの参照が存在しないことを保証することです。Disposeビットマップをカプセル化するオブジェクトを呼び出すと、そのオブジェクトへの参照は破棄されたビットマップオブジェクトへの参照になります。他のコードがまだそれを使用することを期待している間にオブジェクトが時期尚早に削除された場合、ビットマップクラスは他のコードが予測可能な方法で失敗することを保証できます。対照的に、解放されたメモリへの参照を使用することは、未定義の動作です。
supercat

34

ガベージコレクションとは、基本的に、割り当てられたオブジェクトが到達できなくなった時点で自動的に解放されることを意味します。

より正確に言えば、それらはプログラムに到達できなくなったときに解放されます。そうしないと、循環参照されるオブジェクトは決して解放されないからです。

スマートポインターとは、通常のポインターのように動作するが、追加の機能が付加された構造を指します。これらに、割り当て解除だけでなく、コピーオンライト、バインドされたチェックなども含まれます。

さて、あなたが述べたように、スマートポインターを使用して、ガベージコレクションの形式を実装できます

しかし、思考の流れは次のようになります。

  1. ガベージコレクションは便利で、面倒を見る必要がないので、持っておくと良いものです。
  2. そのため、自分の言語でガベージコレクションが必要です
  3. さて、GCをどのように私の言語に入れることができますか?

もちろん、最初からこのように設計できます。C#はガベージコレクションを行うように設計されているためnew、参照がスコープ外になったときにオブジェクトとオブジェクトのみが解放されます。これを行う方法はコンパイラ次第です。

しかし、C ++では、ガベージコレクションは意図されていませんでした。ポインターを割り当ててint* p = new int;スコープ外になった場合、pそれ自体はスタックから削除されますが、割り当てられたメモリを管理する人はいません。

今、あなたが最初から持っている唯一のものは決定論的なデストラクタです。オブジェクトが作成されたスコープを離れると、そのデストラクタが呼び出されます。テンプレートおよび演算子のオーバーロードと組み合わせて、ポインターのように動作するラッパーオブジェクトを設計できますが、デストラクタ機能を使用して、それに接続されたリソース(RAII)をクリーンアップします。これをスマートポインターと呼びます

これはすべてC ++固有です。演算子のオーバーロード、テンプレート、デストラクタなどです。この特定の言語の状況では、必要なGCを提供するスマートポインターを開発しました。

ただし、最初からGCを使用して言語を設計する場合、これは実装の詳細にすぎません。オブジェクトがクリーンアップされると言うだけで、コンパイラがこれを行います。

C ++のようなスマートポインターは、決定論的な破壊をまったく持たないC#のような言語ではおそらく不可能です(C#は.Dispose()、特定のオブジェクトでを呼び出すための構文シュガーを提供することでこれを回避します)。参照されていないリソースは最終的にGCによって回収されますが、正確にこれが発生するときは未定義です。

そしてこれにより、GCがより効率的に作業を行えるようになります。.NET GCは、その上に設定されているスマートポインターよりも言語に深く組み込まれているため、メモリ操作を遅延させてブロック単位で実行することで、より安価にしたり、オブジェクトの頻度に基づいて効率を上げるためにメモリを移動したりできますアクセスされます。


C#には、IDisposableおよびを介した決定論的な破壊の形式がありusingます。しかし、それはプログラマの努力を少し必要とします。そのため、通常はデータベース接続ハンドルなどの非常に乏しいリソースにのみ使用されます。
ձոգչJSB

7
@JSBangs:そのとおりです。C ++がRAIIの周りにスマートポインターを構築してGCを取得するのと同様に、C#は逆の方法でGCの周りに「スマートディスポーザー」を構築してRAIIを取得します;)安全なリソース処理。例えばF#が単純しようとするIDisposableだけで、従来を交換して構文をlet ident = valueすることによってuse ident = value...
ダリオ

@Dario:「C#は逆になり、GCの周りに「スマートディスポーザ」を構築してRAIIを取得します」。C#のRAIIはusingガベージコレクションとはまったく関係なく、変数がC ++のデストラクタのようにスコープから外れると関数を呼び出します。
ジョンハロップ

1
@ジョンハロップ:お願いします?引用する文は、参照カウント/スマートポインター/ガベージコレクションを伴わない単純なC ++デストラクターに関するものです。
ダリオ

1
「ガベージコレクションとは、基本的には、割り当てられたオブジェクトが参照されなくなったときに自動的に解放されることを意味します。...より正確なのは、いつではなく、ある時点で自動的に解放されるということです。whenは、開拓がすぐに起こることを暗示していること注意してください。
トッドリーマン

4

私の考えでは、ガベージコレクションとメモリ管理に使用されるスマートポインターには2つの大きな違いがあります。

  1. スマートポインターは循環ガベージを収集できません。ゴミ収集缶
  2. スマートポインターは、アプリケーションスレッドで参照、逆参照、および割り当て解除の瞬間にすべての作業を行います。ガベージコレクションは不要です

前者は、GCがスマートポインターでは収集できないガベージを収集することを意味します。スマートポインターを使用している場合は、この種のガベージの作成を避けるか、手動で処理する準備をする必要があります。

後者は、スマートポインターがどれほどスマートであっても、その操作によりプログラムの作業スレッドが遅くなることを意味します。ガベージコレクションは作業を延期し、他のスレッドに移動できます。それにより、全体的により効率的になります(実際、最新のGCのランタイムコストは、スマートポインターの余分なオーバーヘッドがなくても、通常のmalloc / freeシステムよりも低くなります)。アプリケーションスレッドの方法。

ここで、プログラムの構成要素であるスマートポインターを使用して、ガベージコレクションの範囲外にある他のあらゆる興味深いこと(Darioの答えを参照)を実行できることに注意してください。それらを行いたい場合は、スマートポインターが必要になります。

ただし、メモリ管理の目的上、ガベージコレクションに代わるスマートポインターの見込みはありません。彼らは単にそれが得意ではありません。


6
@Tom:スマートポインターの詳細については、Darioの回答をご覧ください。スマートポインターの利点に関しては、リソース(メモリだけでなく)を制御するために使用すると、決定論的な割り当て解除が大きな利点になります。実際、これは非常に重要であることが証明されているため、MicrosoftはusingC#の後続バージョンにブロックを導入しました。さらに、リアルタイムシステムではGCの非決定的な動作が禁止される場合があります(そのため、GCはそこで使用されません)。また、GCは非常に複雑であるため、ほとんどの場合実際にメモリリークが発生し、非常に効率が悪い(例:Boehm…)。
コンラッドルドルフ

6
GCの非決定性は、ちょっとした赤ニシンです-デスクトップおよびサーバーVMで見られるものはそうではありませんが、リアルタイムの使用に適したGCシステムがあります(IBMのリサイクル業者など)。さらに、スマートポインターを使用することは、malloc / freeを使用することを意味し、mallocの従来の実装は、空きリストを検索する必要があるため、非決定的です。移動GCシステムが持っているより多くのコースの少ないものの、確定解除時間、malloc関数/フリーシステムよりも確定的配分回。
トムアンダーソン

3
複雑さに関して:はい、GCは複雑ですが、「ほとんどの場合実際にメモリをリークし、非常に非効率的である」ことを知らず、そうでなければいくつかの証拠を見ることに興味があります。Boehmは非常に原始的な実装であり、型安全性の欠如により正確なGCが基本的に不可能な言語Cを提供するために構築されているため、証拠ではありません。それは勇敢な努力であり、それがまったく機能することは非常に印象的ですが、GCの見本としてそれを取ることはできません。
トムアンダーソン

8
@ジョン:明らかにでたらめではないbugzilla.novell.com/show_bug.cgi?id=621899または、より一般的に:flyingfrogblog.blogspot.com/2009/01/…これはよく知られ、すべての保守的なGCのプロパティです。
コンラッドルドルフ

3
「最新のGCのランタイムコストは、通常のmalloc / freeシステムよりも低くなっています。」ここにニシン。これは、従来のmallocがひどく非効率的なアルゴリズムだからです。異なるブロックサイズの複数のバケットを使用する最新のアロケーターは、割り当てがはるかに高速で、ヒープの断片化が発生しにくく、高速な割り当て解除が可能です。
メイソンウィーラー

3

ガベージコレクションという用語は、収集するガベージがあることを意味します。C ++では、スマートポインターには複数のフレーバーがあり、最も重要なのはunique_ptrです。unique_ptrは、基本的に単一の所有権とスコープ構造です。適切に設計されたコードでは、ほとんどのヒープに割り当てられたものは通常unique_ptrスマートポインターの背後にあり、これらのリソースの所有権は常に適切に定義されます。unique_ptrにはオーバーヘッドがほとんどなく、unique_ptrは、伝統的に人々を管理された言語に追い込んだ手動メモリ管理の問題のほとんどを取り除きます。より多くのコアが同時に実行されるようになった現在、パフォーマンスを向上させるために、任意の時点で一意で明確に定義された所有権を使用するようにコードを駆動する設計原則がより重要になっています。

適切に設計されたプログラム、特にマルチスレッド環境でも、共有データ構造なしではすべてを表現できるわけではなく、本当に必要なデータ構造では、スレッドが通信する必要があります。c ++のRAIIは、シングルスレッド設定でのライフタイムの問題に対して非常によく機能します。マルチスレッド設定では、オブジェクトのライフタイムが階層的に完全にスタック定義されない場合があります。これらの状況では、shared_ptrの使用がソリューションの大部分を提供します。リソースの共有所有権を作成し、これがC ++で唯一のガベージを見る場所ですが、適切に設計されたc ++プログラムは、完全なガベージコレクションよりも、共有PTRを使用した「リター」コレクションを実装するために考慮する必要があります他の言語で実装されています。C ++には、それほど多くの「ゴミ」はありません

他の人が述べたように、参照カウントのスマートポインターはガベージコレクションの1つの形式であり、そのためには1つの大きな問題があります。参照カウント形式のガベージコレクションの欠点として主に使用される例は、互いに収集されないオブジェクトクラスターを作成するスマートポインターで互いに接続された孤立したデータ構造の作成に関する問題です。計算のアクターモデルに従って設計されたプログラムでは、大部分で主に使用されるように、マルチスレッドプログラミングに幅広い共有データアプローチを使用する場合、データ構造は通常、C ++でそのような収集不可能なクラスターを発生させません業界では、これらの孤立したクラスターがすぐに現実になる可能性があります。

つまり、共有ポインターの使用によって、unique_ptrの幅広い使用と、マルチスレッドプログラミングのための計算手法のアクターモデルとshared_ptrの限定的な使用を意味する場合、他の形式のガベージコレクションは何も買わない追加の利点。しかし、すべてを共有するアプローチでは、場所全体でshared_ptrが必要になる場合は、同時実行モデルの切り替え、または所有権のより広い共有とデータ構造への同時アクセスを対象としたマネージ言語への切り替えを検討する必要があります。


1
Rustガベージコレクションが必要ないということですか?
グルシャン

1
@Gulshan Rustは、安全な一意のポインターをサポートする数少ない言語の1つです。
CodesInChaos

2

ほとんどのスマートポインターは、参照カウントを使用して実装されます。つまり、オブジェクトを参照する各スマートポインターは、オブジェクトの参照カウントを増やします。そのカウントがゼロになると、オブジェクトは解放されます。

問題は、循環参照がある場合です。つまり、AにはBへの参照があり、BにはCへの参照があり、CにはAへの参照があります。スマートポインターを使用している場合、A、BおよびCに関連付けられたメモリを解放するには、手動でそこに循環参照を「ブレーク」します(weak_ptrC ++で使用するなど)。

ガベージコレクション(通常)の動作はまったく異なります。最近のほとんどのガベージコレクターは、到達可能性テストを使用しています。つまり、スタック上の参照とグローバルにアクセス可能なもののすべてを見て、その後、すべてのは、それらの参照が参照するオブジェクトトレースし、あり、そしてオブジェクト彼らは他のすべてがゴミであるなど、を参照してください。

この方法では、循環参照はもはや重要ではありません-A、B、Cのいずれにも到達できない限り、メモリを再利用できます。

「実際の」ガベージコレクションには他にも利点があります。たとえば、メモリ割り当ては非常に安価です。メモリブロックの「終了」へのポインタを増やすだけです。割り当て解除には、一定の償却コストもあります。しかし、もちろんC ++のような言語を使用すると、メモリ管理を自由に実装できます。そのため、より高速な割り当て戦略を思い付くことができます。

もちろん、C ++では、ヒープに割り当てられたメモリの量は通常、C#/。NETなどの参照が多い言語よりも少なくなります。しかし、それは実際にはガベージコレクションとスマートポインターの問題ではありません。

いずれにせよ、この問題は、一方が他方より優れているということではありません。それぞれに長所と短所があります。


2

パフォーマンスについてです。メモリの割り当てを解除するには、多くの管理が必要です。割り当て解除がバックグラウンドで実行される場合、フォアグラウンドプロセスのパフォーマンスが向上します。残念ながら、メモリ割り当ては遅延することはできません(割り当てられたオブジェクトは次の聖なる瞬間に使用されます)が、オブジェクトを解放することはできます。

C ++(GCなし)で試して、大量のオブジェクトを割り当て、「hello」を出力してから削除します。オブジェクトを解放するのにどれくらい時間がかかるか驚くでしょう。

また、GNU libcはメモリの割り当てを解除するためのより効果的なツールを提供します。obstacksを参照してください。気づかなければならない、私はobstacksの経験がなく、それらを使ったことがない。


原則としてポイントがありますが、これは非常に単純な解決策がある問題であることに注意する必要があります。プールアロケーターまたは小さなオブジェクトアロケーターを使用して、割り当て解除をバンドルします。ただし、これはGCをバックグラウンドで実行するよりも(わずかに)努力が必要です。
コンラッドルドルフ

確かに、GCははるかに快適です。(特に初心者向け:所有権の問題はなく、削除演算子さえありません。)
ern0

3
@ ern0:いいえ。(参照カウント)スマートポインターのポイントは、所有権の問題や削除演算子がないことです。
コンラッドルドルフ

3
@Jon:正直なところ、ほとんどの場合です。異なるスレッド間でオブジェクトの状態を自由に共有すると、まったく異なる問題が発生します。多くの人々がそのようにプログラムすることを認めますが、これは最近まで存在していた悪いスレッド抽象化の結果であり、マルチスレッドを行う良い方法ではありません。
コンラッドルドルフ

1
多くの場合、割り当て解除は「バックグラウンド」ではなく、すべてのフォアグラウンドスレッドを一時停止します。バッチモードのガベージコレクションは、フォアグラウンドスレッドの一時停止にもかかわらず、一般にパフォーマンスの向上につながります。これは、未使用の領域を統合できるためです。ガベージコレクションとヒープのコンパクト化のプロセスを分離することもできますが、特にハンドルではなく直接参照を使用するフレームワークでは、どちらも「世界を停止する」プロセスになる傾向があり、それらを実行するのが最も実用的です。一緒。
-supercat

2

ガベージコレクションはより効率的になる可能性があります。基本的には、メモリ管理のオーバーヘッドを「まとめ」、一度にすべて処理します。一般に、これによりメモリの割り当て解除に費やされる全体的なCPUは少なくなりますが、それはある時点で割り当て解除アクティビティの大きなバーストがあることを意味します。GCが適切に設計されていないと、GCがメモリの割り当てを解除しようとしている間、これが「一時停止」としてユーザーに表示される可能性があります。最近のGCのほとんどは、最も悪条件の場合を除いて、ユーザーにこれを見えないようにするのに非常に優れています。

スマートポインター(または任意の参照カウントスキーム)には、コードを見たときに正確に発生するという利点があります(スマートポインターが範囲外になると、事が削除されます)。あちこちで割り当て解除のバーストが少し発生します。全体的に割り当て解除により多くのCPU時間を使用する可能性がありますが、プログラムで発生しているすべての事柄に分散しているため、ユーザーに表示される可能性は低くなります(一部のモンスターデータ構造の割り当て解除がむき出しになります)。

応答性が重要な場所で何かをしている場合、スマートポインター/参照カウントを使用すると、発生していることを正確に知ることができるため、コーディング中にユーザーに表示される可能性が高いものを知ることができます。GCの設定では、ガベージコレクターを制御するのは最も短命であり、単純に回避する必要があります。

一方、全体的なスループットを目標とする場合は、メモリ管理に必要なリソースを最小限に抑えるため、GCベースのシステムの方がはるかに優れた選択肢です。

サイクル:サイクルの問題を重要な問題とは考えていません。スマートポインターを使用するシステムでは、サイクルを持たないデータ構造を使用する傾向があるか、単純にそのようなものを手放すことに注意します。必要に応じて、所有オブジェクト内のサイクルを破壊する方法を知っているキーパーオブジェクトを使用して、適切な破壊を自動的に保証できます。プログラミングの一部の領域では、これは重要な場合がありますが、ほとんどの日常業務では関係ありません。


1
「ある時点で、割り当て解除アクティビティが大量に発生します」。Bakerのトレッドミルは、美しくインクリメンタルなガベージコレクターの例です。memorymanagement.org/glossary/t.html#treadmill
ジョン・ハロップ

1

スマートポインターの最大の制限は、循環参照に対して常に役立つとは限らないことです。たとえば、オブジェクトAにオブジェクトBへのスマートポインターを格納し、オブジェクトBにオブジェクトAへのスマートポインターを格納しているとします。どちらもポインターをリセットせずに残しておくと、割り当てが解除されることはありません。

これは、両方のオブジェクトがプログラムに到達できないため、スマートポインターが特定のアクションを実行する必要があるためです。ガベージコレクションは対処します-オブジェクトがプログラムに到達できないことを適切に識別し、それらが収集されます。


1

それはスペクトルです。

パフォーマンスを厳しく制限せず、グラインドを実行する準備ができている場合は、アセンブリまたはcで終了します。 、それを台無しにするすべての自由:

「何をすべきか教えてあげる、あなたはそれをする。私を信じて」。

ガベージコレクションは、スペクトルのもう一方の端です。あなたにはほとんど制御がありませんが、それはあなたのために世話をしました:

「私が欲しいものを教えます、あなたはそれを実現させます」。

これには多くの利点があります。ほとんどの場合、リソースが不要になった時期を正確に知ることに関してはそれほど信頼できる必要はありませんが、(ここに浮かぶ答えのいくつかにもかかわらず)パフォーマンスには向いていません。パフォーマンスの予測可能性。(すべてのことと同様に、コントロールを与えられて愚かなことをすると、悪い結果になる可能性があります。しかし、コンパイル時にメモリを解放できる条件を知ることは、パフォーマンスの向上として使用できないことを示唆するためです。ナイーブを超えて)。

RAII、スコーピング、参照カウントなどはすべて、そのスペクトルに沿ってさらに移動できるようにするためのヘルパーですが、そこまで行くことはできません。これらはすべて、引き続き積極的に使用する必要があります。ガベージコレクションとは異なる方法で、メモリ管理とやり取りするように要求します。


0

結局、すべてが命令を実行するCPUに要約されることを覚えておいてください。私の知る限り、すべてのコンシューマグレードのCPUには命令セットがあり、メモリ内の特定の場所にデータを保存する必要があり、そのデータへのポインタがあります。それが基本レベルのすべてです。

それに加えて、ガベージコレクション、移動された可能性のあるデータへの参照、ヒープコンパクションなどが、上記の「アドレスポインター付きメモリチャンク」パラダイムによって与えられた制限内で作業を行っています。スマートポインターについても同じことです。実際のハードウェアでコードを実行する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.