2011-10-03 24 views
0

一段時間我試圖調試我的算法,在兩個數據庫之間同步數據。一切日常使用幾個月的工作確定,最近奇怪的事情開始發生如:C#windows服務的奇怪行爲,而> 90%的RAM使用

  • 「DisableBuyButton」屬性有時設置爲true,而它被明確設置爲false,在配置文件中(我已加強通過算法的方式太多次發現一個奇怪的現象 - 什麼也沒發現,雖然在我的機器都這樣做也沒關係)
  • 產品被分配到不同的類別高於預期

和許多類似的錯誤。

然後我想起在一個CodeCamp會議上有人說,在調試ASP.NET應用程序時,他們遇到了垃圾回收器處於某種「恐慌模式」的問題 - 這導致了許多意想不到的錯誤發生。

我檢查了可用內存量 - > 90%的使用量。我解決了這個問題,只需在虛擬機上添加1GB或更多的RAM即可 - 所有這些奇怪的事情都消失在一片空氣中。

現在的問題:這是甚麼可能是遠程可能的?

//編輯:關鍵部分,以確保只有一個實例在運行:

 lock (this) 
     { 
      if (WorkStarted) 
      { 
       return; 
      } 
      else 
      { 
       WorkStarted = true; 
      } 
     } 
+1

我來自密蘇里州。給我看看。 –

+0

難道你的代碼不是線程安全的嗎?可能不是,根據你的描述,但是如果你的代碼是多線程的並且編碼錯誤,那麼重載計算機的行爲就會很差。 –

+0

實際上它是,但關鍵的部分 - 導致問題的只有一個線程,並與其他線程共享任何內容。另一個線程用於計劃和運行作業,但一次只能有一個線程完成這項工作。上面是確保只有一個實例正在運行的代碼。 – kubal5003

回答

2

有涉及到肯定的因素太多,但一個潛在的問題是沉默的回退爲默認值(比如你試圖每次訪問屬性時從配置文件加載,但如果不能,則返回默認值)。

另一個問題和潛在的問題是緩存使用情況。您可能會遇到競態條件或暫停將某些值重置爲空,與上述情況相結合可能會產生有趣的情況。這可能只發生在一段時間內無法訪問的情況下(通常情況下,該流程會在下一次訪問時重新啓動並重新啓動)或處理高內存情況。

垃圾收集器基本上不會隨意翻轉位(或刪除可訪問的對象),但它可能會在我們添加的抽象層之後執行某些操作。

編輯:

對不起,長篇大論的反應,題目是非常複雜的,而且我想給普遍適用的建議。

讓我們看一個緩存的簡單示例,該緩存按照上次訪問的時間對所有內容進行排序,並在GC運行的情況下將最早的20%的數字放入WeakReference對象中。然後您可以從緩存中獲取信息,但因爲它可能已過期,請檢查它是否存在。這就要求WeakReferenceHasValue屬性返回true。最後,你去讀對象,但在GC運行並殺死對象之前。緩存優雅地返回null,但現在您的項目有一個null它預期的價值。不用擔心異常處理例程檢測到錯誤,而是決定返回默認值(false,如果是bool)。

這一切都結合在一起,創造了一種情況,即您的代碼無法實現,但它具有不正確的值,如果您暫時不回撥高速緩存,此問題可能會持續一段時間。如果您的緩存通過刪除數據來響應GC呼叫,可能會出現類似的情況,這可能在代碼的「安全」部分中。

這些類型的問題的最佳解決方案是按照您的緩存使用指南來寫信,或者如果您自己推出,請確保您瞭解您正在使用的任何交互,例如WeakReference和GC工作方式,或掛在GC過程中的奇怪時機問題。

例如使用HasValueWeakReference不是一個好主意,如果你真的想要的價值。相反,你應該得到Value,這將在最壞的情況下返回null,並測試null而不是(或者在那個時候,你可以打電話HasValue,因爲如果你有一個指向對象的引用GC不會干擾,毫無意義,當null檢查會做)

+0

對不起,我沒有更清楚地說:我的應用程序不是一個ASP.NET頁面 - 它是Windows服務,所以這裏沒有任何東西被重新啓動或回收。 – kubal5003

+0

@ kubal5003:關於緩存的要點仍然適用,您可能直接使用某種緩存或可能間接使用緩存。由於這些經常試圖和垃圾收集器一起玩,因此頻繁收集可能會在奇怪的角落案例中造成問題。 – Guvante

+0

你可以寫更多的關於它或給我一些鏈接/線索尋找什麼?我真的很想進一步調查這一點,因爲我不太喜歡談論編程時使用的「怪異」一詞。 – kubal5003