8

たとえば、C# 4 に「delete」キーワードを含めるとします。参照ベースのシステムにより、ワイルド ポインターがまったくないことを保証できますが、ガベージ コレクターに依存することはできますか? ?

それが起こっている可能性を確認できる唯一の方法は、メモリ位置への参照の代わりに、参照が実際のオブジェクトへのポインタのテーブルへのインデックスになる場合です。ただし、それが壊れる条件がいくつかあると確信しており、タイプの安全性を破ったり、ポインターがぶら下がったりする可能性があります。

編集: .net だけについて話しているわけではありません。例としてC#を使用していました。

4

9 に答える 9

3

次のようなことができます: オブジェクトを使い捨てにしてから、自分で破棄します。

手動で削除しても、管理された環境でメモリ パフォーマンスが向上する可能性はほとんどありません。管理されていないリソース、つまり処分とは何かに役立つかもしれません。

Disposable オブジェクトの実装と使用をより簡単にしたいのです。これがどのように見えるべきか、一貫した完全なアイデアはありませんが、管理されていないリソースを管理することは、.NET の下では面倒な作業です。


delete を実装するためのアイデア: delete は、手動で削除するオブジェクトにタグを付けます。次のガベージ コレクション サイクルで、オブジェクトは削除され、そのオブジェクトへのすべての参照が null に設定されます。

最初は(少なくとも私には)クールに聞こえますが、役に立つとは思えません。これも特に安全ではありません。たとえば、別のスレッドがそのオブジェクトのメンバー メソッドの実行でビジーである可能性があります。たとえば、オブジェクト データにアクセスするときに、そのようなメソッドをスローする必要があります。

于 2008-10-25T12:27:23.313 に答える
2

ガベージ コレクションを使用すると、オブジェクトへの参照が存在する限り、オブジェクトは存続します。手動削除では、それを保証することはできません。

例 (疑似コード):

obj1 = new instance;
obj2 = obj1;

// 

delete obj2;
// obj1 now references the twilightzone.

手短に言えば、手動のメモリ管理とガベージ コレクションを組み合わせると、GC の目的が無効になります。その上、なぜわざわざ?また、本当に制御したい場合は、C# ではなく C++ を使用してください。;-)。

于 2008-10-25T12:13:59.740 に答える
1

あなたが得ることができる最善の方法は、1 つの半球が管理され、ダングリング ポインターが存在しないことを保証できる、2 つの「半球」へのパーティションです。もう一方の半球には明示的なメモリ管理があり、保証はありません。この 2 つは共存できますが、いいえ、第 2 半球に強力な保証を与えることはできません。できることは、すべてのポインターを追跡することだけです。1 つが削除されると、同じインスタンスへの他のすべてのポインターがゼロに設定される可能性があります。言うまでもなく、これはかなり高価です。あなたのテーブルは役に立ちますが、他のコストが発生します (二重の間接参照)。

于 2008-10-25T12:14:32.080 に答える
0

C++ などの非マネージ言語で可能であり、既に実装されています。基本的には、既存のガベージ コレクターを実装または使用します。手動でメモリを管理する場合は、通常どおり new と delete を呼び出します。ガベージ コレクションが必要な場合は、GC_MALLOC またはガベージ コレクター用の関数またはマクロを呼び出します。

例については、 http://www.hpl.hp.com/personal/Hans_Boehm/gc/を参照してください。

例として C# を使用していたので、マネージ言語で手動のメモリ管理を実装することだけを念頭に置いていたかもしれませんが、これはその逆が可能であることを示しています。

于 2009-08-15T00:10:20.957 に答える
0

はい...しかし、多少の虐待があります。

それを実現するために、C# を少し悪用することができます。Marshalクラス、StructLayout属性、およびをいじってみたい場合はunsafe code、独自の手動メモリ マネージャーを作成できます。

ここで概念のデモンストレーションを見つけることができます: C# でマニュアル メモリ マネージャーを書く

于 2011-12-19T19:11:38.320 に答える
0

私の最初の反応は次のとおりでした。あなたがやりたいことは、参照されていないチャンクをヒープに残して後で再び見つけるようなものだとは想像できません。あたかも、ヒープへの 4 バイトのポインターを維持するには多すぎて、このチャンクを追跡できないかのように。

したがって、問題は参照されていないメモリを割り当てたままにするのではなく、参照中のメモリを意図的に破棄することです。ガベージ コレクションはある時点でメモリを解放する機能を実行するため、この特定のメモリ チャンクを破棄するには、別の命令シーケンスを呼び出すだけでよいように思われます。

ただし、問題は次の場所にあります。

String s = "Here is a string."; 
String t = s;
String u = s;
junk( s );

何をし、何tu指していますか?厳密な参照システムでは、tuある必要がありますnull。つまり、参照カウントだけでなく、おそらく追跡も行う必要があります。

ただし、コードのこの時点で終了する必要があることがわかります。sそのjunkため、参照を null に設定し、一種の優先度コードを使用してスイーパーに渡すことができます。制限付きの実行のために gc をアクティブにすることができ、到達できない場合にのみメモリが解放されます。したがって、誰かが何らかの方法で再び使用するためにコード化したものを明示的に解放することはできません。しかしsが唯一の参照である場合、チャンクは割り当て解除されます。

したがって、明示的な側面に限定的に固執する場合にのみ機能すると思います。

于 2008-10-25T23:04:31.357 に答える
0

Chris Sells も .NET Rocks でこれについて議論しました。初登場時だったと思いますが、その後のインタビューでこの話題が再検討された可能性があります。

http://www.dotnetrocks.com/default.aspx?showNum=10

于 2008-10-25T14:43:20.943 に答える
0

これは、存続期間の長いオブジェクトを使用する状況で役立ちます。ガベージ コレクションは、オブジェクトが短期間使用され、すぐに参照解除される場合にうまく機能します。問題は、一部のオブジェクトが長期間存続する場合です。それらをクリーンアップする唯一の方法は、リソースを集中的に使用するガベージ コレクションを実行することです。

このような状況では、オブジェクトを明示的に削除する方法、または少なくともオブジェクトのグラフをジェネレーション 0 に戻す方法があれば、作業はずっと簡単になります。

于 2010-08-16T08:48:16.920 に答える
0

オブジェクトの参照に対する削除のセマンティクスにより、そのオブジェクトを参照する他のすべての参照が null になる場合は、2 レベルの間接化 (ヒントよりも 1 つ多い) でそれを行うことができます。ただし、基になるオブジェクトが破棄される間、一定量の情報 (参照を保持するのに十分な量) をヒープ上に保持する必要があることに注意してください。

ユーザーが使用するすべての参照は、実際のオブジェクトへの非表示の参照 (おそらくヒープ内にある) を参照します。オブジェクトに対して何らかの操作を行う場合 (メソッドの呼び出しや、== 演算子の使用など、その ID に依存するなど)、プログラマーが使用する参照は、それが指している非表示の参照を逆参照します。オブジェクトを削除すると、実際のオブジェクトがヒープから削除され、非表示の参照が null に設定されます。したがって、プログラマーが見る参照は null と評価されます。

これらの非表示の参照を一掃するのは GC の仕事です。

于 2010-01-30T04:14:09.710 に答える