簡體   English   中英

C#-在調用GC.Collect之前為GC准備對象

[英]C# - Preparing An Object For GC Before Calling GC.Collect

情境

  • 可以說,我已經決定確實需要調用GC.Collect();。
  • 在實際調用此方法之前,我需要做些什么來確保准備好適當地垃圾回收對象?
  • 將null分配給對象的所有屬性是否足夠? 還是只為對象本身分配null?

如果您真的需要知道為什么.....

  • 我在WCF中有一個分布式應用程序,該應用程序每隔幾秒鍾通過電線發送一個DataContract,其中包含8個字典作為DataMembers。
  • 這是大量數據,當它進入客戶端接口時,會創建一個全新的DataContract對象,並且應用程序的內存使用量正在增長,以至於我收到OutOfMemory Exceptions。

謝謝

編輯

感謝您的所有評論和回答,似乎每個人都有相同的看法。

  • 我不明白的是,由於連接一直處於打開狀態,我如何正確處理。
  • 一旦從傳入對象復制了數據,就不再需要該對象,那么僅在該DataContract對象上實現IDisposable就足夠了嗎?
  • 我的原始問題在這里- 分布式OutOfMemory異常

只要沒有其他東西可以看到該對象 ,則該對象已經可以收集。 不再需要。 這里的關鍵點是確保沒有其他人在看它(或者至少沒有任何人有更長的壽命):

  • 在某個地方的田野里嗎?
  • 是在不完整的方法中的變量中嗎? (也許是無限循環或迭代器塊)
  • 在某個地方的收藏中嗎?
  • 它訂閱了某個活動嗎?
  • 它被捕獲在一個還活着的閉包(lambda /匿名方法)中?

我真的懷疑GC.Collect()是這里的答案。 如果符合條件,它將已經被收集。 如果不是 elgible,調用GC.Collect()當然不會幫助,很可能會讓事情變得更糟(由占用CPU沒事的時候非常有用,可以收集)。

您通常不需要執行任何操作。

如果該對象不再被引用,則它是一個候選集合。 (相反,如果仍引用該對象,則該對象不是收集對象,但是您可以“准備”該對象。)

您需要清理所有非托管資源,例如數據庫連接等。
通常通過實現IDisposable並調用Dispose

如果您有終結器,則應致電GC.SuppressFinilize

其余的由垃圾收集器清理。

編輯:
而且,哦,自然地,您需要釋放對對象的所有引用。

但是 ,這是很大的。 除非您有非常特殊的情況,否則不需要調用GC.Collect。 您可能會忘記釋放一些資源或參考,而GC.Collect將無法為您提供幫助。 確保對所有Disposable(最好使用using模式)調用Dispose

您可能應該選擇像Ants內存探查器這樣的內存探查器,並查看所有內存都去了哪里。

如果沒有更多直接引用對象,並且內存不足,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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM