我有一个C#服务,它监听队列以接收XML消息,并使用XSLTs处理它们并将它们写入数据库。每天大约处理60K个1Mb大小的消息。当处于空闲状态时,内存降至100MB,这非常好。 但是,最近我开始处理12 MB大小的消息。它会使内存爆炸,即使处于空闲状态,内存也会达到500MB左右。有什么建议吗?我不认为存在内存泄漏,因为在处理如此多(60K个1MB)的消息后,它应该已经出现了。
看起来完全没有问题,你为什么认为这是个问题呢?
垃圾回收器最终会释放未使用的内存,但这并不意味着当您的服务处于空闲状态时就会立即发生。
Raymond Chen写了一篇很好的文章,解释了垃圾回收的基本思想:
然而 - 这只是根据您提供的信息进行的纯粹推测 - 您的XSLT中可能与扩展方法相关的内存泄漏。在每次转换新的XML文档时重新编译样式表可能会导致问题。解决方法很简单:一旦编译,缓存样式表。
SIR!放下任务管理器并离开。认真对待.NET中的内存管理,不要追求最小的占用空间,而是要追求效率。它会保留内存而不将其释放回系统。除非出现实际问题(OOM异常、系统问题),否则请抵制 babysit 内存的诱惑。
XmlDocument
),则需要更多的内存(许多链接到其他节点)。可以考虑使用不同的模型(XDocument
和XPathDocument
都更轻量级),或者更好地使用XmlReader
处理XML,从而永远不会有完全扩展的对象模型。GC.Collect(2)
以确保实际收集具有终结器的对象而不仅仅是终结器。)public class Publisher
: IDisposable
{
private EventHandler _somethingHappened;
public event EventHandler SomethingHappened
{
add { _somethingHappened += value; }
remove { _somethingHappened -= value; }
}
protected void OnSomethingHappened(object sender, EventArgs e)
{
if (_somethingHappened != null)
_somethingHappened(sender, e);
}
public void Dispose()
{
_somethingHappened = null;
}
}
public class Subscriber
: IDisposable
{
private Publisher _publisher;
public Publisher Publisher
{
get { return _publisher; }
set {
// Detach from the old reference
DetachEvents(_publisher);
_publisher = value;
// Attach to the new
AttachEvents(_publisher);
}
}
private void DetachEvents(Publisher publisher)
{
if (publisher != null)
{
publisher.SomethingHappened -= new EventHandler(publisher_SomethingHappened);
}
}
private void AttachEvents(Publisher publisher)
{
if (publisher != null)
{
publisher.SomethingHappened += new EventHandler(publisher_SomethingHappened);
}
}
void publisher_SomethingHappened(object sender, EventArgs e)
{
// DO STUFF
}
public void Dispose()
{
// Detach from reference
DetachEvents(Publisher);
}
}