2013-10-15 80 views
2

我在我的rebus處理程序中看到了一個非常奇怪的行爲,這個行爲是在exe中自行託管的。在使用bus.send方法發送響應之後,它會添加進程使用的一些內存。我嘗試使用內存配置文件查找對象圖,發現rebus在某處以串行格式保存響應消息。 對象圖在層次結構下顯示爲根。
System.Message - > CachedBodyMessage - > stream從rebus處理器發送響應時發生內存泄漏

給我一些指示,如果有人知道這件事。

回答

0

我知道內存泄漏是一個嚴重的問題,但我的看法是,Rebus不太可能包含內存泄漏。

這種看法的根源在於,我已經在生產中運行了Windows服務託管的Rebus終端1.5年了,其中一些終端(例如超時管理器)有時已經運行了好幾個月而沒有重新啓動。

雖然我想確保絕對無懈可擊,所以我願意調查您報告的問題。

你提到「CachedBodyMessage」 - 根據System.Messaging.Message中的字段名稱判斷,它聽起來像是MSMQ中的東西。要嘗試重現您的問題,我編寫了以下測試:

[Test, Ignore("Only works in RELEASE mode because otherwise object references are held on to for the duration of the method")] 
public void DoesNotLeakMessages() 
{ 
    // arrange 
    const string inputQueueName = "test.leak.input"; 
    var queue = new MsmqMessageQueue(inputQueueName); 
    disposables.Add(queue); 

    var body = Encoding.UTF8.GetBytes(new string('*', 32768)); 
    var message = new TransportMessageToSend 
        { 
         Headers = new Dictionary<string, object> { { Headers.MessageId, "msg-1" } }, 
         Body = body 
        }; 

    var weakMessageRef = new WeakReference(message); 
    var weakBodyRef = new WeakReference(body); 


    // act 
    queue.Send(inputQueueName, message, new NoTransaction()); 
    message = null; 
    body = null; 

    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 

    // assert 
    Assert.That(weakMessageRef.IsAlive, Is.False, "Expected the message to have been collected"); 
    Assert.That(weakBodyRef.IsAlive, Is.False, "Expected the body bytes to have been collected"); 
} 

它證明發送交通信息被收集,因爲它應該(只會做這在釋放模式,但因爲方式DEBUG模式持有以範圍內的對象引用)

我會嘗試立即運行TimePrinter示例並讓它運行一段時間,以查看是否可以重現此問題。如果您偶然發現更多關於如確切地哪些物體泄漏,這將是非常有幫助的。

再次感謝您抽出寶貴時間來您的後顧之憂報告給我:)

跟帖:

,使其發送50味精/秒,包括64 KB我已經修改了TimePrinter樣本隨機字符串有效載荷與每條消息,我已經跟蹤了近四個小時的內存使用情況。正如你所看到的,它看起來並不像內存泄漏。

Perfmon memory trace

我會離開它運行一天的休息,只是要確定。

也許你可以告訴我更多關於你爲什麼懷疑首先存在內存泄漏的問題?

更新:

你可以從跟蹤看,現在已經運行了7小時,含有超過70 GB的數據從而更加的1,200,000消息已經通過相同的方法發送和消費。如果緩存的郵件正在泄漏,我很確定我們能夠看到圖表上的某些東西正在上升。

Perfmon memory trace 2