我不断收到下面代码中的'System.OutOfMemoryException'。我无法弄清楚内存泄漏的位置,如果有人能够解释我做错了什么,这将是一个很大的帮助。谢谢!
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();
}
}
}
编辑:回答几个问题:
编辑2: 感谢所有的投入。添加使用并寻找其他可能的内存泄漏似乎是最好的方法。很高兴看到人们可以多快帮忙!
答案 0 :(得分:3)
你确定问题出在这里吗?
你不是在其他地方泄露记忆吗?
OutOfMemoryException可以从任何地方抛出内存分配,这可能只是巧合,它发生在这里。
尝试在内存分析器中分析应用程序,看看是否持有一些会导致内存“泄漏”的引用。
尝试尽可能多地从测试计算机中删除RAM(取决于操作系统,尝试在XP上降至256/128 MB)并多次运行重复用例(不一定只是运行此操作的用例)码)。
答案 1 :(得分:0)
根据_tabs
的大小,您通过sr.ReadToEnd()
读取整个序列化流的事实可能会导致它。
答案 2 :(得分:0)
它正在为一两个使用块而尖叫。
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();
}
}
}
答案 3 :(得分:0)
像其他人说的那样,我会怀疑_tabs。
将Visual Studio设置为在抛出的异常时中断并检查其大小。
如果您要简单地使用Dispose,为什么不使用嵌套的'using'块而不是finally块?
当出现内存不足异常时,正在运行多少个线程?您的代码块可能在内存已被使用时挂起。
答案 4 :(得分:0)
试试这个.. 这在SnippetCompiler中运行。如果它不起作用,那么tsgClsTab类中有一个循环引用。 并且,是的,查找'using'; - )
using System;
using System.Collections;
using System.IO;
using System.Xml.Serialization;
public class MyClass
{
public static void RunSnippet()
{
var _tabs = new ArrayList();
_tabs.Add(new tsgClsTab(1));
_tabs.Add(new tsgClsTab(2));
_tabs.Add(new tsgClsTab(3));
_tabs.Add(new tsgClsTab(4));
lock ((_tabs))
{
StreamReader sr = null;
MemoryStream ms = null;
try
{
var srl = new XmlSerializer(typeof (ArrayList),
new Type[] {typeof (tsgClsTab)});
ms = new MemoryStream();
srl.Serialize(ms, _tabs);
ms.Seek(0, 0);
sr = new StreamReader(ms);
Console.WriteLine(sr.ReadToEnd());
}
finally
{
if (((sr != null)))
{
sr.Close();
sr.Dispose();
}
if (((ms != null)))
{
ms.Close();
ms.Dispose();
}
}
}
}
#region Helper methods
public static void Main()
{
try
{
RunSnippet();
}
catch (Exception e)
{
string error = string.Format("---\nThe following error occurred while executing the snippet:\n{0}\n---",
e.ToString());
Console.WriteLine(error);
}
finally
{
Console.Write("Press any key to continue...");
Console.ReadKey();
}
}
#endregion
#region Nested type: tsgClsTab
public class tsgClsTab
{
public tsgClsTab()
{
}
public tsgClsTab(int id)
{
Id = id;
}
public int Id { get; set; }
}
#endregion
}
输出
<?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>
答案 5 :(得分:0)
这是另一个建议,如果你可以摆动它。使用强类型泛型替换_tabs
'声明(我假设声明为ArrayList
somwhere):
old:private ArrayList _tabs = new ArrayList();
新:private List<tsgPublicDecs.tsgClsTab> _tabs = new List<tsgPublicDecs.tsgClsTab>();
同样调整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。但只有一万个这些项目的arraylist,每个项目都参考前一个项目。所以当它落到它时它是一个非常复杂的对象图,这可能就是你遇到的。