C# 代码审查:OutOfMemoryException问题
我一直在下面的代码中抛出“System.OutOfMemoryException”。我不知道内存泄漏在哪里,如果有人能解释我做错了什么,那将是一个很大的帮助。谢谢C# 代码审查:OutOfMemoryException问题,c#,.net,out-of-memory,C#,.net,Out Of Memory,我一直在下面的代码中抛出“System.OutOfMemoryException”。我不知道内存泄漏在哪里,如果有人能解释我做错了什么,那将是一个很大的帮助。谢谢 lock ((_tabs)) { System.IO.StreamReader sr = null; System.IO.MemoryStream ms = null; try { Type[] t = { typeof(tsgPublicDecs.tsgClsTab) };
lock ((_tabs))
{
System.IO.StreamReader sr = null;
System.IO.MemoryStream ms = null;
try
{
Type[] t = { typeof(tsgPublicDecs.tsgClsTab) };
System.Xml.Serialization.XmlSerializer srl = new System.Xml.Serialization.XmlSerializer(typeof(ArrayList), t);
ms = new System.IO.MemoryStream();
srl.Serialize(ms, _tabs);
ms.Seek(0, 0);
sr = new System.IO.StreamReader(ms);
return sr.ReadToEnd();
}
finally
{
if (((sr != null)))
{
sr.Close();
sr.Dispose();
}
if (((ms != null)))
{
ms.Close();
ms.Dispose();
}
}
}
编辑:回答以下几个问题:
- _选项卡中没有填充任何内容(这就引出了许多其他问题,为什么要使用它,但我需要询问编写它的开发人员)
- 引发错误的行是“srl.Serialize(ms,_tabs);”李>
- 这个错误是随机的,我自己也无法复制它,但是让它运行几天就会抛出。因此,除了抛出的错误之外,我无法(不知道如何)获得任何信息
谢谢大家的意见。添加using并查找其他可能的内存泄漏似乎是最好的方法。很高兴看到人们能这么快伸出援手 根据选项卡的大小,您通过
sr.ReadToEnd()
读取整个序列化流的事实可能会导致此问题 需要一两个使用块
lock ((_tabs))
{
Type[] t = { typeof(tsgPublicDecs.tsgClsTab) };
System.Xml.Serialization.XmlSerializer srl = new System.Xml.Serialization.XmlSerializer(typeof(ArrayList), t);
using ( System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
srl.Serialize(ms, _tabs);
ms.Seek(0, 0);
using (System.IO.StreamReader sr = new System.IO.StreamReader(ms))
{
return sr.ReadToEnd();
}
}
}
<?xml version="1.0"?>
<ArrayOfAnyType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<anyType xsi:type="tsgClsTab">
<Id>1</Id>
</anyType>
<anyType xsi:type="tsgClsTab">
<Id>2</Id>
</anyType>
<anyType xsi:type="tsgClsTab">
<Id>3</Id>
</anyType>
<anyType xsi:type="tsgClsTab">
<Id>4</Id>
</anyType>
</ArrayOfAnyType>
1.
2.
3.
4.
您确定问题在这里吗
你不是在别的地方泄露内存吗
OutOfMemoryException可以从任何地方在内存分配时抛出,它发生在这里可能只是巧合
尝试在内存分析器中分析应用程序,以查看您是否持有一些会导致内存“泄漏”的引用
尝试从您的测试机中删除尽可能多的RAM(根据操作系统的不同,在XP上尝试降低到256/128 MB),并多次运行重复的用例(不一定只运行此代码的用例)。如果您可以改变它,这里还有另一个建议。用强类型泛型替换
\u tabs
'声明(我假设声明为ArrayList
somwhere):
旧:private ArrayList\u tabs=new ArrayList()代码>
新建:private List_tabs=new List()代码>
并以类似方式调整XmlSerializer
实例化
这就是说,经过一些非常基本的测试,我无法得到任何OOM异常发生。以下是其他人所说的使用简化:
lock (_tabs)
{
Type[] t = { typeof(tsgPublicDecs.tsgClsTab) };
System.Xml.Serialization.XmlSerializer srl = new System.Xml.Serialization.XmlSerializer(typeof(ArrayList), t);
using (System.IO.Stream ms = new System.IO.MemoryStream())
{
srl.Serialize(ms, _tabs);
ms.Seek(0, 0);
using (System.IO.TextReader sr = new System.IO.StreamReader(ms))
{
return sr.ReadToEnd();
}
}
}
编辑:你猜怎么着?我能够使OutOfMemoryException发生。但是只有这些项目中有10000个的arraylist,每个项目都有对前一个项目的引用。因此,当深入到它时,它是一个相当复杂的对象图,这可能就是您遇到的情况。如果要使用“try”,它应该是try{}catch(exception){}finally{}。也就是说,您错过了catchline抛出异常的原因是什么?在阻止IO之类的调用时保持锁几乎总是一个坏主意。顺便说一句,当抛出异常时,您可以发布堆栈跟踪吗?所有这些额外的括号都起作用了吗?如果(((ms!=nul)))是,将抛出哪一行异常?假设_tabs确实是tsgPublicDecs.tsgClsTab类型,那么它的大小/对象图对于序列化的性能和随后对该流的重新读取至关重要。话虽如此,我希望一堆括号不会占用内存。这段代码不会工作(或编译)。A) 您不需要带有“using”的finally块,并且B)您使用的MemoryStream超出了其作用域。这需要一个嵌套的using块。此外,即使此代码如kervin所述格式正确,它仍然无法解决您的内存不足问题,因为它只提供语法调整。(当然,这并不是说使用块不是一件美妙的事情。)好的,我错过了ms参数。固定的。这里没有finally块。虽然这段代码确实更干净,但就内存使用而言,它在语义上是相同的。这个问题清楚地表明他正在处理MemoryStream和StreamReader实例。为什么这是公认的答案?stewsha说异常可以追溯到Serialize()行;sr.ReadToEnd()引起这种情况的唯一方法是调用sr.ReadToEndAsync()
lock (_tabs)
{
Type[] t = { typeof(tsgPublicDecs.tsgClsTab) };
System.Xml.Serialization.XmlSerializer srl = new System.Xml.Serialization.XmlSerializer(typeof(ArrayList), t);
using (System.IO.Stream ms = new System.IO.MemoryStream())
{
srl.Serialize(ms, _tabs);
ms.Seek(0, 0);
using (System.IO.TextReader sr = new System.IO.StreamReader(ms))
{
return sr.ReadToEnd();
}
}
}