回答
ガベージコレクションには次のデータ構造が必要です割り当ての追跡および/または参照カウント。これらは、メモリ、パフォーマンス、および言語の複雑さにオーバーヘッドをもたらします。 C ++は「金属に近い」ように設計されています。つまり、便利な機能とのトレードオフのパフォーマンスの面で優れています。他の言語では、そのトレードオフが異なります。これは、言語を選択する際の考慮事項の1つであり、どちらを強調するかを選択します。
とはいえ、C ++にはかなり軽量でパフォーマンスの高い参照カウントのスキームがたくさんありますが、それらは言語自体の一部ではなく、商用とオープンソースの両方のライブラリにあります。オブジェクトの存続期間を管理するための参照カウントは、ガベージコレクションと同じではありませんが、同じ種類の問題の多くに対処し、C ++の基本的なアプローチにより適しています。
コメント
回答
厳密に言えば、 C言語ではメモリ管理はまったくありません。 malloc()とfree()は言語のキーワードではなく、ライブラリから呼び出される関数にすぎません。malloc()とfree()はC標準ライブラリの一部であり、Cの標準準拠の実装によって提供されるため、この区別は今ではわかりにくいかもしれませんが、これは過去に常に当てはまるとは限りませんでした。
メモリ管理の標準がない言語が必要なのはなぜですか?これは、Cの起源である「ポータブルアセンブリ」にまでさかのぼります。特殊なメモリ管理技術の恩恵を受ける、または必要とするハードウェアとアルゴリズムのケースは数多くあります。私の知る限り、Javaのネイティブメモリ管理を完全に無効にして独自のメモリ管理に置き換える方法はありません。これは、一部の高性能/最小限のリソースの状況では受け入れられません。Cは、正確にどのインフラストラクチャを選択するかをほぼ完全に柔軟に選択できます。あなたのプログラムが使用する予定です。支払われる代償は、C言語が正しいバグのないコードを書くのにほとんど役に立たないということです。
コメント
シンプルでわかりやすく、舞台裏に隠されています。静的メモリ割り当ての設計は、スタックやその他の利用可能なものをうまく利用するのと同様に、依然としてメモリ管理です。
"標準に準拠した実装"は当てはまりません。これは、標準に準拠したホスト環境の実装の場合のみです。一部のプラットフォーム/標準ライブラリは、ほとんどが8ビットまたは16ビットの組み込みマイクロコントローラー用であり、malloc()
またはfree()
を提供していません。 (例はMLAP-PIC用コンパイラです)
回答
本当の答えは、作成する唯一の方法です。安全で効率的なガベージコレクションメカニズムは、不透明な参照に対して言語レベルのサポートを用意することです。 (または、逆に、直接メモリ操作の言語レベルのサポートが不足します。)
JavaとC#は、操作できない特別な参照型があるため、これを実行できます。これにより、ランタイムは割り当てられたオブジェクトをメモリに移動するなどの操作を自由に行うことができます。これは、高性能GCの実装に不可欠です。 。
ちなみに、最近のGC実装では参照カウントを使用していませんなので、完全に赤です。ニシン。最新のGCは世代別コレクションを使用します。このコレクションでは、スタック割り当てがC ++などの言語で行われるのと基本的に同じ方法で新しい割り当てが処理され、その後、まだ生きている新しく割り当てられたオブジェクトが定期的に別の「サバイバー」スペースに移動され、世代全体が移動されます。オブジェクトの割り当てが一度に解除されます。
このアプローチには長所と短所があります。利点は、GCをサポートする言語でのヒープ割り当てがスタック割り当てと同じくらい速いことですはGCをサポートしていない言語であり、欠点は、破棄する前にクリーンアップを実行する必要があるオブジェクトには、別のメカニズム(C#などusing
キーワード)またはクリーンアップコードが非決定的に実行されます。
高性能GCの1つの鍵は、特別なクラスの参照に対する言語サポートが必要であることです。 Cはこの言語をサポートしておらず、決してサポートしません。C++には演算子のオーバーロードがあるため、慎重に行う必要がありますが、GCのポインタ型をエミュレートできます。実際、MicrosoftがCLR(.NETランタイム)で実行されるC ++のダイアレクトを発明したとき、「C#スタイルの参照」の新しい構文を発明する必要がありました(例:Foo^
)「C ++スタイルの参照」(例:Foo&
)と区別するため。
C ++には何があり、C ++プログラマーが定期的に使用するものは次のとおりです。 スマートポインターは、実際には単なる参照カウントメカニズムです。参照カウントを「真の」GCとは見なしませんが、手動のメモリ管理や真のGCよりもパフォーマンスが低下するという犠牲を払って、同じ利点の多くを提供しますが、決定論的な破壊という利点があります。
結局のところ、答えは本当に言語設計機能に要約されます。Cは1つの選択を行い、C ++は、Cとの下位互換性を可能にすると同時に、十分に優れた代替手段を提供する選択を行いました。ほとんどの目的で、JavaとC#は、Cと互換性がないが、ほとんどの目的には十分な別の選択を行いました。残念ながら、特効薬はありませんが、さまざまな選択に精通していると、正しい選択を選択するのに役立ちます。現在構築しようとしているプログラムに関係なく。
コメント
回答
回答
「すべて」のガベージコレクターは、メモリ内に参照されていないオブジェクトがあるかどうか、およびそれらが削除されているかどうかを定期的にチェックするプロセスです。 (はい、私はこれがひどく過度に単純化されていることを知っています)。これは言語のプロパティではなく、フレームワークです。
CおよびC ++用に記述されたガベージコレクターがあります-たとえば、これ 。
言語に「追加」されなかった理由の1つは、メモリの管理に独自のコードを使用するため、言語を使用しない既存のコードの量が非常に多いためである可能性があります。 CおよびC ++で記述されたタイプのアプリケーションは、ガベージコレクションプロセスに関連するオーバーヘッドを必要としません。
コメント
回答
Cは、ガベージコレクションがほとんどなかった時代に設計されました。オプション。また、ガベージコレクションが一般的に機能しない用途、つまり最小限のメモリと最小限のランタイムサポートを備えたベアメタルのリアルタイム環境を対象としています。 Cは、64 * K *バイトのメモリを備えたpdp-11で実行された最初のUNIXの実装言語であったことを思い出してください。 C ++は元々Cの拡張でした。選択はすでに行われており、ガベージコレクションを既存の言語に移植するのは非常に困難です。これは1階から組み込む必要がある種類のものです。
回答
正確な見積もりはありませんが、BjarneとHerbSutterの両方が次のように述べています。
C ++にはガベージがないため、ガベージコレクタは必要ありません。
現代ではC ++はスマートポインターを使用するため、ガベージはありません。
コメント
注釈付きC ++リファレンスマニュアル"だと思います。 GCは1959年にLisp用に発明されました。
@ deadalnix-少なくとも1つのJavaVMが、スマートポインタクラスを使用したC ++スタイルのRAIIを使用して(ほぼ)実装できる参照カウントGCを使用したことをご存知ですか。 -正確にはなぜなら既存のVMよりもマルチスレッドコードの方が効率的だったからですか? www.research.ibm.com/people/d/dfb/papers/Bacon01Concurrent.pdfを参照してください。 '実際にC ++でこれが表示されない理由の1つは、通常のGCコレクションです。サイクルを収集できますが、'を選択できません。サイクルが存在する場合の安全なデストラクタの順序であるため、信頼できるデストラクタのクリーンアップを保証できません。
回答
あなたこれらの言語がオプションのガベージコレクターを含むように更新されていない理由を尋ねてください。
オプションのガベージコレクションの問題は、異なるモデルを使用するコードを混在させることができないことです。つまり、ガベージコレクターを使用していると想定するコードを記述した場合、ガベージコレクションがオフになっているプログラムでは使用できません。オフにすると、どこでもリークします。
回答
次のようなさまざまな問題があります…
- GCはC ++の前、場合によってはCの前に発明されましたが、GCが実用的であると広く受け入れられる前にCとC ++の両方が実装されました。
- 簡単に実装することはできません。基盤となる非GC言語のないGC言語とプラットフォーム。
- 典型的なタイムスケールなどで開発された典型的なアプリケーションコードでは、GCは非GCよりも明らかに効率的ですが、より多くの開発努力が良いトレードであるという問題があります。 -オフで特殊なメモリ管理は、汎用GCよりも優れています。さらに、C ++は通常、追加の開発作業がなくても、ほとんどのGC言語よりも明らかに効率的です。
- GCはC ++スタイルのRAIIよりも普遍的に安全ではありません。 。RAIIでは、基本的に信頼性が高くタイムリーなデストラクタをサポートしているため、メモリ以外のリソースを自動的にクリーンアップできます。参照サイクルに問題があるため、これらを従来のGCメソッドと組み合わせることができません。
- GC言語には独自の特徴があります。記憶の種類リーク。特に、二度と使用されないメモリに関連しますが、ヌルアウトまたは上書きされたことがない既存の参照が存在する場合。これを明示的に行う必要性は、原則として、
delete
またはfree
を明示的に行う必要性と同じです。 GCアプローチにはまだ利点があり、ダングリング参照がなく、静的分析で一部のケースを検出できますが、繰り返しになりますが、「すべてのケースに完全な解決策は1つではありません。
基本的に、部分的には」 s言語の時代についてですが、とにかく非GC言語のための場所は常にあります-それが少しニッキーな場所であっても。そして真剣に、C ++では、GCの欠如は大したことではありません。メモリの管理方法は異なりますが、管理されていないわけではありません。
Microsoftが管理するC ++には、GCと非管理を混在させる機能が少なくともある程度あります。同じアプリケーションでGCを使用すると、それぞれの利点を組み合わせることができますが、これが実際にどの程度うまく機能するかを言う経験はありません。
担当者-関連する回答へのリンク私の…
回答
ガベージコレクションを使用する言語でデバイスハンドラーを作成することを想像できますか? GCの実行中にライン?
またはオペレーティングシステム?カーネルを起動する前に、ガベージコレクションの実行を開始するにはどうすればよいですか?
Cは、ハードウェアタスクに近い低レベル向けに設計されています。問題?それはとても素晴らしい言語なので、多くのより高いレベルのタスクにも適しています。言語皇帝はこれらの使用法を認識していますが、優先順位としてデバイスドライバー、組み込みコード、およびオペレーティングシステムの要件をサポートする必要があります。
コメント
回答
この質問に対する短くて退屈な答えは、ガベージコレクターを作成する人々のために、ガベージコレクションされていない言語が必要であるということです。同時にメモリレイアウトを非常に正確に制御できる言語を使用することは概念的に簡単ではありません。 その上でGCを実行します。
もう1つの質問はCとC ++にガベージコレクタがない理由。ええと、C ++にはそれらがいくつかあることは知っていますが、そもそもGCで処理されるように設計されていない言語を扱うことを余儀なくされているため、あまり人気がありません。この時代は、実際にはGCを見逃すようなものではありません。
また、GCを使用しない古い言語にGCを追加する代わりに、ほとんどの言語を備えた新しい言語を作成する方が実際には簡単です。 GCをサポートしながら同じ構文。JavaとC#はこの良い例です。
コメント
回答
ガベージコレクションは基本的にDMA対応ハードウェア用のドライバの開発に使用されるシステム言語。
オブジェクトへの唯一のポインタが一部の周辺機器のハードウェアレジスタに格納される可能性は十分にあります。ガベージコレクタは知らないため、これについては、オブジェクトが到達不能であると見なして収集します。
この引数は、GCを圧縮する場合に2倍になります。ハードウェアペリフェラルによって使用されるオブジェクトへのメモリ内参照を維持するように注意したとしても、GCがオブジェクトを再配置すると、ペリフェラル構成レジスタに含まれるポインタを更新する方法がわかりません。
ここで、不動のDMAバッファとGC管理対象オブジェクトを混在させる必要があります。つまり、両方の欠点がすべてあります。
コメント
回答
C & C ++は比較的低レベルの言語であり、たとえば、組み込みシステムで1MBのメモリを搭載した16ビットプロセッサで実行するため、gcでメモリを浪費する余裕はありませんでした。
コメント
回答
C ++とCにはガベージコレクターがあります。これがCでどのように機能するかはわかりませんが、 C ++では、 RTTI を利用して、オブジェクトグラフを動的に検出し、それをガベージコレクションに使用できます。
私の知る限り、Javaを作成することはできません。ガベージコレクターなし。少し検索すると、これが見つかりました。
JavaとC / C ++の主な違いは、C / C ++では常に選択できることです。 、一方、Javaでは、設計上オプションがないことがよくあります。
コメント
回答
パフォーマンスと安全性のトレードオフです。
ごみがJavaで収集される保証はないため、長い間スペースを使い果たしている可能性がありますが、参照されていないオブジェクト(つまりゴミ)のスキャンには、未使用のオブジェクトを明示的に削除または解放するよりも時間がかかります。
もちろん、その利点は次のとおりです。ポインタやメモリリークなしで言語を構築できるため、正しいコードを生成する可能性が高くなります。
これらの議論には、わずかな「宗教的」なエッジがある場合があります。警告が必要です。
回答
ここに、Cのようなシステム言語で使用できなくなるGCの固有の問題のリストがあります。
-
GCは、オブジェクトを管理するコードのレベルより下で実行する必要があります。カーネルにはそのようなレベルはありません。
-
GCはマネージコードを時々停止する必要があります。それがあなたのカーネルにそれをしたとしたらどうなるか考えてみましょう。 GCが既存のすべてのメモリ割り当てをスキャンしている間、マシン上のすべての処理は、たとえば1ミリ秒停止します。これにより、厳密なリアルタイム要件の下で動作するシステムを作成するすべての試みが無効になります。
-
GCは、ポインターと非ポインターを区別できる必要があります。つまり、存在するすべてのメモリオブジェクトを確認し、そのポインタを見つけることができるオフセットのリストを生成できる必要があります。
この発見は完璧である必要があります:GCは発見したすべてのポインタを追跡します。誤検知を逆参照すると、クラッシュする可能性があります。フォールスネガティブの検出に失敗した場合、まだ使用中のオブジェクトが破壊されたり、マネージコードがクラッシュしたり、データがサイレントに破損したりする可能性があります。
これには、タイプ情報をすべてのオブジェクトに格納する必要があります。オブジェクトは存在します。ただし、CとC ++はどちらも、型情報を含まない単純な古いデータオブジェクトを許可します。
-
GCは本質的に遅いビジネスです。Javaとソーシャル化されたプログラマーこれに気付かないかもしれませんが、Javaで実装されていない場合、プログラムは数桁速くなる可能性があります。Javaを遅くする要因の1つは、GCです。これにより、JavaなどのGCマネージコードをスーパーコンピューティングで使用できなくなります。年間100万の電力消費が必要なため、ガベージコレクションにその10%も支払う必要はありません。
CおよびC ++は、サポートするために作成された言語です。考えられるすべての使用例。そして、ご覧のとおり、これらのユースケースの多くはガベージコレクションによって排除されています。したがって、これらのユースケースをサポートするために、C / C ++をガベージコレクションすることはできません。