Я понимаю, что утечка памяти вызывает серьезную озабоченность, но я считаю, что маловероятно, что Rebus должен содержать утечку памяти.
Это убеждение основано на том факте, что я использую конечные точки Rebus, размещенные в службе Windows, в производственной среде уже 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 сообщений в секунду и включал в каждое сообщение полезную нагрузку случайной строки размером 64 КБ, и я отслеживал использование памяти в течение почти четырех часов. Как видите, это не похоже на утечку памяти.
Я оставлю его включенным до конца дня, просто чтобы быть уверенным.
Может быть, вы можете рассказать мне больше о том, почему вы подозреваете, что произошла утечка памяти?
Обновление:
Как видно из трассировки, он работает уже 7 часов, и, таким образом, одним и тем же процессом было отправлено и использовано более 1 200 000 сообщений, содержащих более 70 ГБ данных. Если бы кешированные тела сообщений просачивались, я почти уверен, что мы смогли бы увидеть рост на графике.
person
mookid8000
schedule
17.10.2013