[英]C# - Preparing An Object For GC Before Calling GC.Collect
謝謝
感謝您的所有評論和回答,似乎每個人都有相同的看法。
只要沒有其他東西可以看到該對象 ,則該對象已經可以收集。 不再需要。 這里的關鍵點是確保沒有其他人在看它(或者至少沒有任何人有更長的壽命):
我真的懷疑GC.Collect()
是這里的答案。 如果符合條件,它將已經被收集。 如果不是 elgible,調用GC.Collect()
當然不會幫助,很可能會讓事情變得更糟(由占用CPU沒事的時候非常有用,可以收集)。
您通常不需要執行任何操作。
如果該對象不再被引用,則它是一個候選集合。 (相反,如果仍引用該對象,則該對象不是收集對象,但是您可以“准備”該對象。)
您需要清理所有非托管資源,例如數據庫連接等。
通常通過實現IDisposable
並調用Dispose
。
如果您有終結器,則應致電GC.SuppressFinilize
。
其余的由垃圾收集器清理。
編輯:
而且,哦,自然地,您需要釋放對對象的所有引用。
但是 ,這是很大的。 除非您有非常特殊的情況,否則不需要調用GC.Collect。 您可能會忘記釋放一些資源或參考,而GC.Collect將無法為您提供幫助。 確保對所有Disposable(最好使用using模式)調用Dispose
。
如果沒有更多直接引用對象,並且內存不足,GC應該自動執行此操作。 確保確保在數據上下文上調用.Dispose()。
調用GC.Collect
幾乎不會阻止您獲得OutOfMemory異常,因為.NET因OOM而無法創建新對象時,它將調用GC.Collect
本身。 我只能想到一種情況,那就是當您在未終結的隊列中注冊了未引用的對象時。 當這些對象引用許多其他對象時,可能會導致OOM。 解決此問題的方法實際上不是調用GC.Collect
而是確保正確放置了這些對象(並在創建這些對象時正確地實現了放置模式)。
一般使用GC.Collect
由於您試圖擺脫一個非常大的集合,因此使用GC.Collect()是完全有效的。 從Microsoft文檔 :
...由於您的應用程序比運行時更了解其行為,因此可以通過顯式強制某些集合來幫助解決問題。 例如,在用戶保存數據文件之后,強制應用程序的所有世代都可能對您的應用程序有意義。
“准備”您的對象
從.NET Framework中的運行時技術出色的性能考慮 (來自MSDN):
如果您保持指向資源的指針,則GC無法知道您將來是否打算使用它。 這意味着您在本機代碼中用於顯式釋放對象的所有規則仍然適用,但是大多數情況下,GC會為您處理所有事情。
因此,要確保已准備好將其用於GC,請確保您沒有對要收集的對象的引用(例如,在收集,事件等中)。 將變量設置為null意味着在變量超出范圍之前可以進行收集。
同樣,任何實現IDisposable的對象都應調用其Dispose()方法來清理非托管資源。
使用GC.Collect之前
由於您的應用程序看起來像是服務器,因此使用Server GC可能會解決您的問題。 在多處理器方案中,它可能會更頻繁地運行並且性能更高。
服務器GC旨在實現最大吞吐量,並具有很高的性能進行擴展。
請參閱在.NET Framework中從運行時技術的性能考慮因素中 選擇使用哪個垃圾收集器 (來自MSDN):
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.