2013-10-15 83 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