我在我的rebus处理程序中看到了一个非常奇怪的行为,它在exe中自托管。在使用bus.send方法发送响应之后,它会增加进程消耗的一些内存。我试图使用内存配置文件查找对象图,发现rebus在某处以序列化格式保存响应消息。 对象图显示在根下面的层次结构中 System.Message - > CachedBodyMessage - >流
如果有人知道这件事,请给我一些指示。
答案 0 :(得分: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");
}
验证发送的传输消息是否按预期收集(虽然只能在RELEASE模式下执行此操作,因为DEBUG模式保留在范围内的对象引用上)
我现在尝试运行TimePrinter示例并让它运行一段时间以查看是否可以重现该问题。如果您偶然发现有关例如究竟哪些物体泄漏,这将非常有帮助。
再次感谢您花时间向我报告您的担忧:)
跟进:
我已经修改了TimePrinter示例,以便它发送50 msg / s并包含每条消息的64 KB随机字符串有效负载,现在我已经跟踪了大约四个小时的内存使用情况。正如您所看到的,它看起来并不像内存泄露。
我会让它在剩下的时间里运行,只是为了确定。
也许你可以先告诉我一些你怀疑是否存在内存泄漏的原因?
更新
从跟踪中可以看出,它现在已经运行了7个小时,因此同一进程已经发送和使用了超过1,200,000条包含70 GB以上数据的消息。如果缓存的邮件正在泄漏,我很确定我们能够在图表上看到一些上升的东西。