我在我的rebus处理程序中看到了一个非常奇怪的行为,这个行为是在exe中自行托管的。在使用bus.send方法发送响应之后,它会添加进程使用的一些内存。我尝试使用内存配置文件查找对象图,发现rebus在某处以串行格式保存响应消息。 对象图在层次结构下显示为根。
System.Message - > CachedBodyMessage - > stream从rebus处理器发送响应时发生内存泄漏
给我一些指示,如果有人知道这件事。
我在我的rebus处理程序中看到了一个非常奇怪的行为,这个行为是在exe中自行托管的。在使用bus.send方法发送响应之后,它会添加进程使用的一些内存。我尝试使用内存配置文件查找对象图,发现rebus在某处以串行格式保存响应消息。 对象图在层次结构下显示为根。
System.Message - > CachedBodyMessage - > stream从rebus处理器发送响应时发生内存泄漏
给我一些指示,如果有人知道这件事。
我知道内存泄漏是一个严重的问题,但我的看法是,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样本随机字符串有效载荷与每条消息,我已经跟踪了近四个小时的内存使用情况。正如你所看到的,它看起来并不像内存泄漏。
我会离开它运行一天的休息,只是要确定。
也许你可以告诉我更多关于你为什么怀疑首先存在内存泄漏的问题?
更新:
你可以从跟踪看,现在已经运行了7小时,含有超过70 GB的数据从而更加的1,200,000消息已经通过相同的方法发送和消费。如果缓存的邮件正在泄漏,我很确定我们能够看到图表上的某些东西正在上升。