Javaにはあるのに、CやC ++などの言語にガベージコレクションがないのはなぜですか?[閉まっている]


57

まあ、Cにはmalloc / free、C ++にはメモリ管理にnew / using-a-de-structorのようなものがあることは知っていますが、ユーザーがこれらの言語に「新しい更新」がないのはなぜだろうメモリを手動で管理するオプションがありますか、またはシステムが自動的にメモリを管理するオプションがあります(ガベージコレクション)。

やや新しい質問ですが、CSに約1年しかいません。


9
今学期、iPhone開発のモジュールがあります。Android用のアプリを2年間コーディングした後、この質問はクラスのほとんどをかなり苦しめました。厄介なメモリ管理エラーを追跡したり、ボイラープレートコードを作成したりする必要がないため、Javaが実際に何時間節約したかがわかります。
siamii

7
@NullUserException。これは、GCをほぼ暗示しているメモリを再生する方法を指定していないためです。
ウィンストンイーバート

1
@ bizso09:ARCはまだ見ましたか?参照カウントのシステムサポートがある場合は、低速/脂肪/非決定性GCは
不要

3
このかなり良い質問への答えは、宗教的なでたらめでいっぱいです。
-abatishchev

1
CおよびC ++では、ポインターを取得してintにキャストし、それに数値を追加することができます。その後、intから数値を減算し、結果をポインターにキャストします。以前と同じポインターを取得します。アドレスが別の値を持つ変数にのみ保存されている間、そのメモリを収集しないGCを実装することで幸運を祈ります。この例は馬鹿げていることは知っていますが、XORリンクリストは似たようなものを使用します。これを回答として投稿しますが、質問は終了しました。
マリアンスパニック

回答:


71

ガベージコレクションには、割り当ての追跡や参照カウントのためのデータ構造が必要です。これらにより、メモリ、パフォーマンス、および言語の複雑さがオーバーヘッドになります。C ++は「金属に近い」ように設計されています。つまり、利便性機能とのトレードオフよりもパフォーマンスの面を重視しています。他の言語では、トレードオフが異なります。これは、言語を選択する際の考慮事項の1つです。

とは言っても、かなり軽量でパフォーマンスの高いC ++の参照カウントには多くのスキームがありますが、それらは言語自体の一部ではなく、商用およびオープンソースの両方のライブラリにあります。オブジェクトの有効期間を管理するための参照カウントは、ガベージコレクションと同じではありませんが、同じ種類の問題の多くに対処し、C ++の基本的なアプローチにより適しています。


26
二次的な問題は、GCが非決定的であることです。オブジェクトは、プログラムがオブジェクトを「ドロップ」した後もメモリ内にある場合とそうでない場合があります。Refcountライフサイクルは確定的であり、最後の参照が削除されると、メモリが削除されます。これは、メモリ効率だけでなく、デバッグにも影響します。一般的なプログラミングエラーは、理論的には削除された参照メモリである「ゾンビ」オブジェクトです。GCはこの効果を隠し、断続的で追跡が非常に困難なバグを生成する可能性がはるかに高くなります。
キルベン

22
-最新のgcは、割り当ての追跡も参照のカウントも行いません。現在スタック上にあるすべてのものからグラフを作成し、他のすべてを単純化して圧縮および消去するだけです。GCは通常、言語の複雑さを減らします。パフォーマンスの利点でさえ疑問です。
ジョエルCoehoorn

13
Er、@ kylben、自動GCを言語に組み込むことの全体的なポイントは、GCが参照できないオブジェクトのみを解放するため、ゾンビオブジェクトを参照できなくなることです!手動のメモリ管理で間違いを犯すと、追跡が困難なバグが発生します。
ベン

14
-1、GCは参照をカウントしません。さらに、メモリ使用量と割り当てスキームによっては、GCが高速になる場合があります(メモリ使用量にオーバーヘッドがあります)。したがって、パフォーマンスに関する議論も誤りです。実際には、金属に近い部分のみが有効なポイントです。
-deadalnix

14
JavaもC#も参照カウントを使用しません:参照カウントに基づくGCスキームは、比較するとかなり原始的であり、最新のガベージコレクターよりもパフォーマンスがはるかに
劣り

44

厳密に言えば、C言語にはメモリ管理はまったくありません。malloc()およびfree()は言語のキーワードではなく、ライブラリから呼び出される関数にすぎません。malloc()とfree()はC標準ライブラリの一部であり、Cの標準に準拠した実装によって提供されるため、この区別は今では教訓的かもしれませんが、これは過去には必ずしも当てはまりませんでした。

メモリ管理の標準がない言語が必要なのはなぜですか?これは、「ポータブルアセンブリ」としてCの起源に戻ります。特殊なメモリ管理技術の恩恵を受けたり、必要とするハードウェアやアルゴリズムの多くのケースがあります。私の知る限り、Javaのネイティブメモリ管理を完全に無効にして独自のメモリ管理に置き換える方法はありません。これは、一部の高性能/最小リソースの状況では受け入れられません。Cは、プログラムが使用するインフラストラクチャを正確に選択するためのほぼ完全な柔軟性を提供します。支払われる代償は、C言語は、バグのない正しいコードを書くのにほとんど役に立たないということです。


2
1全体的に良い答えのための1つが、また、特にため、「支払った価格は、C言語が正しい、バグのないコードを書くことに非常に少しの助けを提供することである」
シヴ山のドラゴン

2
Cにはメモリ管理機能がありますが、動作するだけなので、ほとんど気付かないでしょう。静的メモリ、レジスタ、およびスタックがあります。ヒープから割り当てを開始するまで、あなたは元気です。混乱させるのはヒープの割り当てです。Javaについては、誰でも独自のJavaランタイムを作成できます。「システムのJava」と呼ばれるものも含め、選択できるものはたくさんあります。.NETは、Cができることのほとんどすべてを実行できます。C++のネイティブ機能よりも遅れています(たとえば、クラスは.NETでのみ管理されます)。もちろん、C ++が実行するすべての機能と.NETが実行する機能をすべて備えたC ++。NETもあります。
ルアーン

1
@Luaan「メモリ管理」を持つことは非常に寛大な定義だと思います完全に優れた飛行機で、飛べないだけです。
チャールズE.グラント

1
@ CharlesE.Grantまあ、純粋に機能的な言語は、そのようなメモリ管理ですべてを実行できます。ヒープの割り当てがいくつかのユースケースで良いトレードオフだからといって、それがすべての言語/ランタイムのベンチマークであることを意味するわけではありません。メモリ管理が単純で、単純で、背後に隠れているからといって、メモリ管理が「メモリ管理」でなくなるというわけではありません。静的メモリ割り当ての設計は、スタックやその他の利用可能なものを適切に使用するため、メモリ管理です。
ルアーン

「標準に準拠した実装」は真実ではなく、標準に準拠したホスト環境実装にのみ当てはまります。一部のプラットフォーム/標準ライブラリは、ほとんどが8ビットまたは16ビットの組み込みマイクロコントローラー向けで、提供も提供malloc()もしませんfree()。(例はPICのMLAPコンパイラです)
-12431234123412341234123

32

本当の答えは、安全で効率的なガベージコレクションメカニズムを作成する唯一の方法は、不透明な参照を言語レベルでサポートすることです。(または、逆に、直接メモリ操作に対する言語レベルのサポートの欠如。)

JavaとC#には、操作できない特別な参照型があるため、これを行うことができます。これにより、ランタイムは、割り当てられたオブジェクトをメモリ内で移動するなどのことを自由に行うことができます。これは、高性能GCの実装に不可欠です。

記録に関しては、現代のGC実装では参照カウントを使用していないため、完全に赤いニシンです。最新のGCは世代別コレクションを使用します。この場合、新しい割り当ては、C ++のような言語のスタック割り当てと本質的に同じ方法で処理されます。のオブジェクトの割り当てが一度に解除されます。

このアプローチには長所と短所があります:利点は、GCをサポートする言語でのヒープ割り当てがGCをサポートしない言語でのスタック割り当てと同じくらい速いことであり、欠点はどちらかを破棄する前にクリーンアップを実行する必要があることです別のメカニズム(C#のusingキーワードなど)が必要です。そうでない場合、クリーンアップコードは非決定的に実行されます。

高性能GCの鍵の1つは、特別なクラスの参照に対する言語サポートが必要であることに注意してください。Cはこの言語をサポートしておらず、今後もサポートしません。C ++には演算子のオーバーロードがあるため、GCのポインター型をエミュレートできますが、慎重に行う必要があります。実際、MicrosoftがCLR(.NETランタイム)の下で実行するC ++の方言を発明したときFoo^、「C ++スタイルの参照」と区別するために、「C#スタイルの参照」の新しい構文を考案する必要がありました。 (例Foo&)。

C ++には、C ++プログラマーが定期的に使用しているのは、実際には単なる参照カウントメカニズムであるスマートポインターです。参照カウントは「真の」GCとは見なしませんが、手動メモリ管理や真のGCよりもパフォーマンスが低下するという犠牲を払って、決定的な破壊という利点があるにもかかわらず、多くの同じ利点を提供します。

結局のところ、答えは本当に言語設計機能に帰着します。Cは1つの選択を行い、C ++はほとんどの目的に十分な代替手段を提供しながらCとの下位互換性を可能にする選択を行い、JavaとC#はCとの互換性はないがほとんどの目的。残念ながら、特効薬はありませんが、さまざまな選択肢に精通していれば、現在作成しようとしているプログラムに適した選択肢を選択できます。


4
これは質問に対する実際の答えです。
コアダンプ

1
C ++の部分については、今日では、あなたがSTDをご覧ください:: unique_ptrをとstd ::移動:)
ニクラス・ラーソン

@NiclasLarsson:あなたの主張を理解しているかどうかわかりません。それstd::unique_ptrは「不透明な参照に対する言語レベルのサポート」だと言っていますか?(それは私が意味のサポートのようなものではなかった、と私はまた、ダイレクトメモリ操作のサポートもC ++から削除されない限りそれは十分ではないと思う。)私は私の答えでスマートポインタを言及しない、と私は考えるでしょうstd:unique_ptrスマートポインタを、実際に参照カウントを行うため、参照の数が0または1である(およびstd::move参照カウント更新メカニズムである)特殊なケースのみをサポートします。
ダニエル・プライデン

std::unique_ptr参照カウントを持たず、参照とstd::moveはまったく関係ありません(つまり、パフォーマンスヒットは「ありません」)。ただし、std::shared_ptr暗黙的に参照カウントが更新されているように、std::move:)
ニクラスラーソン

2
@ Mike76:割り当て側では、GCアロケーターはスタック割り当てと同じくらい高速に動作し、GCは同時に何千ものオブジェクトの割り当てを解除できます。ref-countingの実装で何をしようとも、割り当てと割り当て解除は、mallocとより速くなることはありませんfree。そのため、はい、GCは大幅に高速化できます。(「できる」と言ったことに注意してください。もちろん、各プログラムの正確なパフォーマンスは多くの要因の影響を受けます。)
ダニエル・プライデン

27

なぜなら、C ++のパワーを使用する場合、必要がないからです。

ハーブサッター:「長年、削除を書いたことはありません。

最新のC ++コードの記述: 21 : 10でのC ++の進化を参照してください。

多くの経験豊富なC ++プログラマを驚かせるかもしれません。


面白い。今日の私の読書資料。
surfasb

バー、ビデオ。しかし、それでもなお、興味深いものです。
-surfasb

2
面白いビデオ。21分、55分が最高でした。残念ながら、WinRT呼び出しはまだC ++ / CLI bumpfのように見えました。
gbjbaanb

2
@ dan04:それは本当です。しかし、その後、Cで書くと、求めているものが得られます。
-DeadMG

6
スマートポインタの管理は、ガベージコレクション環境で不要な参照がないことを確認することほど難しくありません。GCはあなたの心を読むことができないので、魔法でもありません。
タマスゼレイ

15

「すべて」のガベージコレクターは、メモリ内に参照されていないオブジェクトがあるかどうか、およびそれらが削除されているかどうかを定期的に確認するプロセスです。(はい、これは非常に単純化しすぎです)。これは言語のプロパティではなく、フレームワークのプロパティです。

- CおよびC ++のために書かれたガベージコレクタがあります。この1例は。

言語に「追加」されていない理由の1つは、メモリを管理するために独自のコードを使用するため、決して使用しない既存のコードの膨大な量が原因である可能性があります。別の理由として、CおよびC ++で記述されたタイプのアプリケーションは、ガベージコレクションプロセスに関連するオーバーヘッドを必要としない可能性があります。


1
しかし、書かれた将来のプログラムはガベージコレクターを使用し始めるでしょう?
ダークテンプラー

5
ガベージコレクションは理論的にはどのプログラミング言語からも独立していますが、C / C ++用の便利なGCを書くことは非常に困難であり、フールプルーフ(少なくともJavaのフールプルーフ)を作成することさえ不可能です-Javaがプルできる理由offは、制御された仮想化環境で実行されるためです。逆に、Java言語はGC用に設計されているため、GCを実行しないJavaコンパイラを書くのは大変です。
-tdammers

4
@tdammers:ガベージコレクションを可能にするには、言語でサポートする必要があることに同意します。ただし、主なポイントは仮想化と制御された環境ではなく、厳密なタイピングです。CとC ++は型指定が弱いため、整数変数にポインターを格納したり、オフセットからポインターを再構築したり、コレクターが到達可能なものを確実に認識できないようにするようなものを許可します(C ++ 11では、少なくとも保守的なコレクター)。Javaでは、参照とは何かを常に知っているため、ネイティブにコンパイルされていても正確に収集できます。
ジャン・ヒューデック

2
@ThorbjørnRavnAndersen:ガベージコレクターが見つけられないような方法でポインターを格納する有効なCプログラムを書くことができます。その後、ガベージコレクターをにフックするmallocfree、正しいプログラムが壊れます。
ベンフォークト

2
@ThorbjørnRavnAndersen:いいえ、freeそれが完了するまで電話しません。しかし、私が明示的に呼び出すまでメモリを解放しない提案されたガベージコレクターfreeは、ガベージコレクターではありません。
ベンフォークト

12

Cは、ガベージコレクションがほとんど選択肢にならない時代に設計されました。また、ガベージコレクションが通常機能しない場合の使用を目的としていました-最小限のメモリと最小限のランタイムサポートを備えたベアメタルのリアルタイム環境。Cは最初のUNIXの実装言語であり、64 * K *バイトのメモリを備えたpdp-11上で実行されたことを思い出してください。C ++はもともとCの拡張でした-選択はすでに行われており、ガベージコレクションを既存の言語に移植するのは非常に困難です。1階から組み込まなければならないものです。


9

正確な引用符はありませんが、BjarneとHerb Sutterの両方が次のように述べています。

C ++にはガベージコレクターは必要ありません。ガベージコレクターはガベージがないためです。

最新のC ++では、スマートポインターを使用するため、ゴミがありません。


1
スマートポインターとは何ですか?
ダークテンプラー

11
それがそんなに簡単だったら、誰もGCを実装しなかっただろう。
deadalnix

7
@deadalnix:そうです、誰も過度に複雑な、遅い、肥大化した、または不要なものを実装することはありません。すべてのソフトウェアは常に100%効率的ですよね?
ザック

5
@deadalnix-メモリ管理に対するC ++のアプローチは、ガベージコレクターよりも新しいです。RAIIは、Bjarne Stroustrup for C ++によって発明されました。デストラクタのクリーンアップは古いアイデアですが、例外の安全性を確保するためのルールが重要です。アイデア自体が最初にいつ記述されたのか正確にはわかりませんが、1998年に最初のC ++標準が完成し、Stroustrupsの「Design and Evolution of C ++」は1994年まで公開されず、例外はC ++に比較的最近追加されました- 1990年の「注釈付きC ++リファレンスマニュアル」の発行後、私は信じています。GCは1959年にLisp用に発明されました。
Steve314

1
@deadalnix -少なくとも一つのJava VMが(ほぼ)C ++を使用して実装することができ、参照カウントGCを使用したことをご承知はしている-スマートポインタのクラスを使用して、スタイルRAII -正確ので、それは、既存のVMよりもマルチスレッドコードのためのより効率的でしたか?www.research.ibm.com/people/d/dfb/papers/Bacon01Concurrent.pdfを参照してください。実際にC ++でこれが表示されない理由の1つは、通常のGCコレクションです。サイクルを収集できますが、サイクルが存在する場合は安全なデストラクタの順序を選択できないため、信頼できるデストラクタのクリーンアップを保証できません。
Steve314

8

オプションのガベージコレクタを含めるためにこれらの言語が更新されていない理由を尋ねます。

オプションのガベージコレクションの問題は、異なるモデルを使用するコードを混合できないことです。つまり、ガベージコレクターを使用していることを前提とするコードを記述した場合、ガベージコレクションがオフになっているプログラムでは使用できません。あなたがそうするなら、それはどこにでも漏れます。


6

ガベージコレクションを使用した言語でデバイスハンドラを記述することを想像できますか?GCの実行中に何ビットがラインに届くでしょうか?

またはオペレーティングシステム?カーネルを起動する前に、ガベージコレクションの実行を開始するにはどうすればよいですか?

Cは、ハードウェアタスクに近い低レベル用に設計されています。問題?それは非常に素晴らしい言語であり、多くの高レベルのタスクにも適しています。言語皇帝はこれらの使用法を認識していますが、デバイスドライバー、組み込みコード、およびオペレーティングシステムの要件を優先度としてサポートする必要があります。


2
Cは高レベルに適していますか?私は自分の飲み物をキーボード全体で鳴らしました。
DeadMG

5
まあ、彼は「多くのより高いレベルのタスク」と言いました。彼トロールを数えることできます(1、2、多く...)。そして彼は実際に何よりも高いとは言わなかった。冗談はさておき、それは真実です-多くの重要な高レベルのプロジェクト Cで正常に開発されたという証拠です。これらのプロジェクトの多くには現在、より良い選択肢があるかもしれませんが、作業中のプロジェクトは、なっている。
Steve314

管理されたオペレーティングシステムがいくつかあり、それらはかなりうまく機能します。実際、システム全体を管理対象にすると、マネージコードの使用によるパフォーマンスヒットはさらに低下し、実際のシナリオではアンマネージコードより高速になります。もちろん、これらはすべて「研究OS」です。マネージドOS内で完全に仮想化されたアンマネージドOSを作成する以外に、既存のアンマネージドコードと互換性を持たせる方法はほとんどありません。マイクロソフトは、.NETでより多くのサーバーコードが記述されているため、Windows Serverをそれらのいずれかに置き換えることを、ある時点で提案しました。
ルアーン

6

この質問に対する簡潔で退屈な答えは、ガベージコレクターを作成する人々のために、ガベージコレクションされていない言語が必要であるということです。それは同時に、メモリレイアウトを非常に正確に制御することができます言語持っている概念的に簡単ではありませんし、上で実行されているGCを持っています。

もう1つの質問は、CおよびC ++にガベージコレクターがない理由です。まあ、私はC ++がそれらのいくつかを持っていることを知っていますが、そもそもGCで処理されるように設計されていない言語と、この時代は、GCを見逃すようなものではありません。

また、GCを古いGC以外の言語に追加する代わりに、GCをサポートしながらほとんど同じ構文を持つ新しい言語を実際に作成する方が簡単です。JavaとC#はこの良い例です。


1
Programmers.seまたはSOのどこかで、誰かが自己ブートストラップガベージコレクションの作業に取り組んでいるという主張があります-IIRCは基本的にGC言語を使用してVMを実装し、ブートストラップサブセットはGC自体の実装に使用されます。名前を忘れてしまいました。私が調べたところ、GCなしのサブセットからワーキングGCレベルへの飛躍は基本的に達成されなかったことが判明しました。これ原理的に可能ですが、実際には達成されたことはありません-それは確かに物事を困難な方法で行う場合です。
Steve314

@ Steve314:見つけた場所を覚えているなら、ぜひ見たいです!
hugomg

それを見つけた!stackoverflow.com/questions/3317329/…へのコメントを参照してください。KleinVMを参照してください。それを見つける問題の一部-質問は閉じられました。
Steve314

ところで-@missingnoでコメントを開始できないようです-何が得られますか?
Steve314

@ steve314:このスレッドが添付されている答えを読んだので、私はすでにすべてのコメントの通知を受け取っています。この場合@ポストを実行することは冗長であり、SEによって許可されていません(理由を聞かないでください)。(しかし、本当の原因は私の番号が欠落しているためです)
hugomg

5

など、さまざまな問題があります...

  • GCはC ++の前に、おそらくCの前に発明されましたが、GCが実際に広く受け入れられる前にCとC ++の両方が実装されました。
  • 基礎となる非GC言語がなければ、GC言語とプラットフォームを簡単に実装することはできません。
  • GCは、典型的なタイムスケールなどで開発された典型的なアプリケーションコードに対して非GCよりも明らかに効率的ですが、より多くの開発努力がトレードオフであり、特殊なメモリ管理が汎用GCよりも優れているという問題があります。それに加えて、C ++は通常、追加の開発作業がなくても、ほとんどのGC言語よりも明らかに効率的です。
  • GCは、C ++スタイルのRAIIよりも一般的に安全ではありません。RAIIでは、基本的に信頼性が高くタイムリーなデストラクタがサポートされているため、メモリ以外のリソースを自動的にクリーンアップできます。これらは、参照サイクルに問題があるため、従来のGCメソッドと組み合わせることはできません。
  • GC言語には、特有の種類のメモリリークがあります。特に、再び使用されることのないメモリに関連していますが、既存の参照が存在し、nullアウトまたは上書きされたことはありません。明示的にこれを行う必要性は、原則的に、deleteまたはfree明示的に行う必要性と同じです。GCアプローチにはまだ利点があります-ぶら下がり参照はありません-静的解析はいくつかのケースをキャッチできますが、すべてのケースに完璧なソリューションはありません。

基本的に、部分的には言語の年齢についてですが、とにかく非GC言語の場所は常にあります-たとえそれがちょっとニチャイの場所であっても。そして真剣に、C ++では、GCの欠如は大したことではありません-あなたのメモリは異なって管理されますが、管理されていません。

Microsoftが管理するC ++には、同じアプリケーションでGCと非GCを混在させる機能が少なくともいくつかあり、それぞれの利点を組み合わせて使用​​できますが、実際にこれがどの程度うまく機能するかを経験することはできません。

私の関連する回答への担当者リンク...


4

ガベージコレクションは、DMA対応ハードウェアのドライバーの開発に使用されるシステム言語と基本的に互換性がありません。

オブジェクトへの唯一のポインタが周辺機器のハードウェアレジスタに格納されることは完全に可能です。ガベージコレクターはこれを知らないため、オブジェクトが到達不能であると判断し、収集します。

この引数は、GCを圧縮するためにdoubleを保持します。ハードウェアペリフェラルで使用されるオブジェクトへのメモリ内参照を慎重に維持したとしても、GCがオブジェクトを再配置したとき、ペリフェラル構成レジスタに含まれるポインタを更新する方法がわかりません。

そのため、固定DMAバッファーとGC管理オブジェクトの混合が必要になります。つまり、両方の欠点がすべてあります。


おそらく両方のすべての欠点がありますが、それぞれの欠点の例は少なく、利点も同じです。明らかに、より多くの種類のメモリ管理を行うには複雑さがありますが、コード内の各コースに適切な馬を選択することで、複雑さを回避することもできます。ありそうもないと思いますが、そこには理論上のギャップがあります。以前は同じ言語でGCと非GCを混在させることを想定していましたが、デバイスドライバー用ではありません。主にGCアプリケーションを持っているが、手動でメモリ管理された低レベルのデータ構造ライブラリがあります。
Steve314

@ Steve314:どのオブジェクトを手動で解放する必要があるかを思い出すことは、すべてを解放することを覚えるのと同じくらい厄介だと思いませんか?(もちろん、スマートポインターはどちらにも役立ちますので、どちらも大きな問題ではありません)手動で管理されるオブジェクトと収集/コンパクト化可能なオブジェクトには、異なるオブジェクトが必要です。だから何もせずに余分な複雑さがたくさん。
ベンフォークト

2
すべてのGCである高レベルのコードと、GCをオプトアウトする低レベルのコードとの間に明確な隔たりがある場合ではありません。私は主に数年前にDを見ながらアイデアを開発しました。これにより、GCをオプトアウトできますが、オプトインできません。たとえば、B +ツリーライブラリを見てみましょう。コンテナ全体はGCである必要がありますが、データ構造ノードはおそらくそうではありません-ブランチノードを再帰的に検索するよりもリーフノードをカスタマイズしたスキャンを行う方が効率的です。ただし、そのスキャンでは、含まれているアイテムをGCに報告する必要があります。
Steve314

ポイントは、それが機能の一部であるということです。特別なWRTメモリ管理としてB +ツリーのノードを処理する特別なWRTとしてそれらを治療に違いはありませんである B +ツリーのノード。これはカプセル化されたライブラリであり、アプリケーションコードはGCの動作がバイパス/特殊なケースになっていることを知る必要はありません。ただし、少なくともその時点ではDでは不可能でしたが、私が言ったように、オプトインして含まれるアイテムを潜在的なGCルートとしてGCに報告する方法はありません。
Steve314

3

なぜなら、C&C ++は、たとえば、組み込みシステムで1MBのメモリを搭載した16ビットプロセッサで実行するための汎用目的の比較的低レベルの言語であり、gcでメモリを浪費する余裕がないためです。


1
「組み込みシステム」?Cが標準化されたとき(1989年)、1 MBのメモリを搭載したPCを処理できる必要がありました。
dan04

私は同意する、私はより最新の例を引用していた。
ペトルザ

1MB ??? 聖シュモーリー、だれがそんなに多くのRAMを必要とするだろうか?</ billGates>
マークKコーワン

2

C ++とCにはガベージコレクターがあります。Cでこれがどのように機能するかはわかりませんが、C ++ではRTTIを利用してオブジェクトグラフを動的に検出し、ガベージコレクションに使用できます。

私の知る限り、ガベージコレクタなしでJavaを記述することはできません。ちょっとした検索でこれが判明しました

JavaとC / C ++の主な違いは、C / C ++では常に選択できるのに対して、Javaでは多くの場合設計上のオプションがないことです。


また、専用のガベージコレクターがより適切に実装され、より効率的で、言語により適切に適合していること。:)
マックス

いいえ、RTTIを使用してC / C ++のオブジェクトグラフを動的に検出することはできません。すべてを損なうのは、単純な古いデータオブジェクトです。ガベージコレクターがそのオブジェクト内のポインターと非ポインターを区別できるようにする単純な古いデータオブジェクトに格納されているRTTI情報はありません。さらに悪いことに、ポインターはすべてのハードウェア上で完全に整列する必要はありません。したがって、16バイトのオブジェクトを考えると、64ビットポインターを格納できる場所は9つあります。
cmaster

2

パフォーマンスと安全性のトレードオフです。

ガベージがJavaで収集されるという保証はないため、長い間スペースを使い果たしている可能性がありますが、参照されていないオブジェクト(つまり、ガベージ)のスキャンは、未使用のオブジェクトを明示的に削除または解放するよりも時間がかかります

利点は、もちろん、ポインタやメモリリークなしで言語を構築できることです。そのため、正しいコードを生成する可能性が高くなります。

これらの議論には、時々「宗教的」な縁があるかもしれません-注意してください!


1

以下に、Cのようなシステム言語で使用できないGC固有の問題のリストを示します。

  • GCは、オブジェクトを管理するコードのレベル以下で実行する必要があります。カーネルにはそのようなレベルはありません。

  • GCは時々マネージコードを停止する必要があります。次に、カーネルにそれを実行するとどうなるかを考えます。マシン上のすべての処理は、たとえば1ミリ秒間停止しますが、GCは既存のメモリ割り当てをすべてスキャンします。これは、厳しいリアルタイム要件の下で動作するシステムを作成するすべての試みを殺すでしょう。

  • GCは、ポインターと非ポインターを区別できる必要があります。つまり、存在するすべてのメモリオブジェクトを確認し、そのポインタが見つかるオフセットのリストを作成できる必要があります。

    この発見は完璧でなければなりません。GCは発見したすべてのポインタを追跡できなければなりません。誤検知を逆参照すると、クラッシュする可能性があります。偽陰性の発見に失敗した場合、まだ使用中のオブジェクトが破壊され、マネージコードがクラッシュしたり、データが静かに破損したりする可能性があります。

    これには、存在するすべてのオブジェクトに型情報を保存することが絶対に必要です。ただし、CとC ++はどちらも、型情報を含まない単純な古いデータオブジェクトを許可します。

  • GCは本質的に遅いビジネスです。Javaでソーシャル化されたプログラマーはこれに気付かないかもしれませんが、Javaで実装されていない場合、プログラムは桁違いに速くなる可能性があります。また、Javaを遅くする要因の1つはGCです。これは、JavaのようなGC化された言語がスーパーコンピューティングで使用されることを妨げるものです。マシンの消費電力が年間100万ドルの場合、ガベージコレクションにその10%を支払う必要はありません。

CおよびC ++は、考えられるすべてのユースケースをサポートするために作成された言語です。そして、ご覧のとおり、これらのユースケースの多くはガベージコレクションによって除外されています。したがって、これらのユースケースをサポートするために、C / C ++はガベージコレクションできません。

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