System.WeakReferenceのことを理解していますが、私が把握できないようなことは、それが役に立つかもしれない実用的な例です。クラスそのものは、まあ、ハックだと思われます。私が見た例でWeakReferenceが使われている問題を解決するための、より良い手段が他にもあるようです。 WeakReferenceを実際に使用しなければならない場所の正式な例は何ですか? をから遠ざけようとしていないのですか?System.WeakReferenceの実際の使用
答えて
一つの有用な例としては、db4oのオブジェクト指向データベースを実行する男です。そこでは、WeakReferenceは一種のライトキャッシュとして使用されます。アプリケーションが実行している間だけオブジェクトをメモリに保持し、実際のキャッシュを上に置くことができます。
また、弱いイベントハンドラの実装にも使用されます。現在、.NETアプリケーションでのメモリリークの大きな原因の1つは、イベントハンドラを削除することを忘れることです。例えば。
public MyForm()
{
MyApplication.Foo += someHandler;
}
を参照してください。上記のスニペットでは、MyApplicationがメモリ内に存続している限り、MyFormは永久にメモリに保持されます。 10個のMyFormを作成し、それらをすべて閉じると、あなたの10個のMyFormsはまだメモリに残っており、イベントハンドラによって保持されます。
WeakReferenceを入力してください。 WeakReferencesを使用してweakイベントハンドラを構築し、someHandlerがMyApplication.Fooの弱いイベントハンドラであるため、メモリリークを修正できます。
これは単なる理論ではありません。 DidItWith.NETのブログのDustin Campbellは、an implementation of weak event handlersという掲示板をSystem.WeakReferenceで掲示しました。
私は未使用のエントリが自動的にガベージコレクトされているキャッシュを実装するためにそれを使用します。
class Cache<TKey,TValue> : IEnumerable<KeyValuePair<TKey,TValue>>
{ Dictionary<TKey,WeakReference> dict = new Dictionary<TKey,WeakReference>();
public TValue this[TKey key]
{ get {lock(dict){ return getInternal(key);}}
set {lock(dict){ setInteral(key,value);}}
}
void setInteral(TKey key, TValue val)
{ if (dict.ContainsKey(key)) dict[key].Target = val;
else dict.Add(key,new WeakReference(val));
}
public void Clear() { dict.Clear(); }
/// <summary>Removes any dead weak references</summary>
/// <returns>The number of cleaned-up weak references</returns>
public int CleanUp()
{ List<TKey> toRemove = new List<TKey>(dict.Count);
foreach(KeyValuePair<TKey,WeakReference> kv in dict)
{ if (!kv.Value.IsAlive) toRemove.Add(kv.Key);
}
foreach (TKey k in toRemove) dict.Remove(k);
return toRemove.Count;
}
public bool Contains(string key)
{ lock (dict) { return containsInternal(key); }
}
bool containsInternal(TKey key)
{ return (dict.ContainsKey(key) && dict[key].IsAlive);
}
public bool Exists(Predicate<TValue> match)
{ if (match==null) throw new ArgumentNullException("match");
lock (dict)
{ foreach (WeakReference weakref in dict.Values)
{ if ( weakref.IsAlive
&& match((TValue) weakref.Target)) return true;
}
}
return false;
}
/* ... */
}
ミックスインでの状態保持に弱いリファレンスを使用しています。ミックスインは静的であることを覚えておいてください。静的オブジェクトを使用して非静的オブジェクトに状態をアタッチする場合、必要な時間は決してわかりません。だから、私はをつけておくのではなく、mixinが長すぎるものをドラッグするのを防ぐためにDictionary<WeakReference,myvalue>
を守っています。
唯一の問題は、私がアクセスするたびに、私も死んだ参照をチェックし、それらを削除することです。もちろん、数千人がいなければ、誰もが傷つけるわけではありません。
WeakReference
を使用する理由は2つあります。代わりにグローバルオブジェクトの
静的として宣言:
AppDomain
がGC'edれるまで静的フィールドおよび静的フィールドが(ガベージコレクション)をGC'edすることができないなどのグローバルオブジェクトが宣言されています。したがって、メモリ不足例外が発生する可能性があります。代わりに、WeakReference
にグローバルオブジェクトをラップすることができます。WeakReference
自体は静的であると宣言されていますが、メモリが少ないときは、そのオブジェクトが指し示すオブジェクトはGC'edされます。基本的には、
staticObject
の代わりにwrStaticObject
を使用しています。class ThingsWrapper { //private static object staticObject = new object(); private static WeakReference wrStaticObject = new WeakReference(new object()); }
AppDomainのときに静的オブジェクトがガベージコレクションされることを証明する簡単なアプリケーション。即ちGC'ed
AppDomain
がGC'edされたとき -staticThing
次の出力からclass StaticGarbageTest { public static void Main1() { var s = new ThingsWrapper(); s = null; GC.Collect(); GC.WaitForPendingFinalizers(); } } class ThingsWrapper { private static Thing staticThing = new Thing("staticThing"); private Thing privateThing = new Thing("privateThing"); ~ThingsWrapper() { Console.WriteLine("~ThingsWrapper"); } } class Thing { protected string name; public Thing(string name) { this.name = name; Console.WriteLine("Thing() " + name); } public override string ToString() { return name; } ~Thing() { Console.WriteLine("~Thing() " + name); } }
注非常に
ThingsWrapper
であっても後の終わりにGC'edれます。Thing() staticThing Thing() privateThing ~Thing() privateThing ~ThingsWrapper ~Thing() staticThing
代わりに、私たちは
WeakReference
でThing
をラップすることができます。wrStaticThing
はGCで処理することができるので、簡潔にするために除外した遅延ロードメソッドが必要です。 GCスレッドが呼び出されたときにそのwrStaticThing
以下の出力からclass WeakReferenceTest { public static void Main1() { var s = new WeakReferenceThing(); s = null; GC.Collect(); GC.WaitForPendingFinalizers(); if (WeakReferenceThing.wrStaticThing.IsAlive) Console.WriteLine("WeakReference: {0}", (Thing)WeakReferenceThing.wrStaticThing.Target); else Console.WriteLine("WeakReference is dead."); } } class WeakReferenceThing { public static WeakReference wrStaticThing; static WeakReferenceThing() { wrStaticThing = new WeakReference(new Thing("wrStaticThing")); } ~WeakReferenceThing() { Console.WriteLine("~WeakReferenceThing"); } //lazy-loaded method to new Thing }
注GC'edれます。時間のかかるを初期化するために、あるオブジェクトの場合
Thing() wrStaticThing ~Thing() wrStaticThing ~WeakReferenceThing WeakReference is dead.
:あなたは時間consusmingがGC'edされるinitにあるオブジェクトを望んでいません。あなたはそれを避けるために静的な参照を維持することができます(上記の点を控えて)。
WeakReference
を使用してください。 EventHandlerの持つ先端のための
- 1. レベルオーダートラバーサルの実際の使用
- 2. インターフェイスイベントの実際の使用
- 3. Vim、実際の使用例
- 4. ReentrantLockのlockInterruptiblyの実際の使用
- 5. 実際のタイプコピーのジェネリックの使用
- 6. 実際のバインディングオブジェクトのルビへの使用
- 7. プロジェクトでのHadoopの実際の使用
- 8. X-Macrosの実際の使用
- 9. JavaScriptストリームの実際の使用例
- 10. キャスティングオペレータの実際の使用例
- 11. XMLの実際の使用ですか?
- 12. Cコーディングトレーニングの実際の使用例
- 13. PHPでの実際の使用方法
- 14. bash配列の実際の使用
- 15. 二重リンクリストの実際の使用
- 16. HttpSessionBindingListenerとHttpSessionAttributeListenerの実際の使用
- 17. RxJavaの実際の使用例件名
- 18. Boost :: MPLの実際的な使用例?
- 19. Keras:実際のGPUメモリ使用量
- 20. 再帰の実際的な使用
- 21. 実際にMath.clz32の使用例
- 22. `stackalloc`キーワードの実際的な使用
- 23. 実際の実装を使用したMockitoモックオブジェクト
- 24. 実際にjstlを使用する
- 25. C#を使用して実際のHTMLを取得する際の問題
- 26. Cでの仮想関数の実際の使用#
- 27. ssisのバッファtempとblob tempの実際の使用方法
- 28. wicketでの実際のHTTPエラーコードの使用
- 29. Spring MVCアプリケーションでの値オブジェクトの実際の使用
- 30. javascriptでのK-combinator(Kestrel)の実際の使用
+1、素晴らしいthatsの!!!! –
ええ、それはかなり気の利いたものです。他のタイプのEventHandler(非ジェネリックなEventHandler、PropertyChangedEventHandlerなど)を扱うために、ここでコードを採用しました。それは私たちのために非常にうまくいきました。 –