问题:在做C#程序时,既然发生[StringBuilder 溢出]
详情如下:
引发类型为“System.OutOfMemoryException”的异常。
在 System.String.GetStringForStringBuilder(String value, Int32 startIndex, Int32 length, Int32 capacity)
在 System.Text.StringBuilder.GetNewString(String currentString, Int32 requiredLength)
在 System.Text.StringBuilder.Append(String value)原因:在调用下面的方法时,有时会产生上面的问题,有时则不会,可以保证的是每一次的数据量是不足于产生于溢出环境:
windows2003
CPU:4核,
内存:6G (运行时只使用不到3G内存),
SQL2005数据库。
取数的表数在1000左右,数据量在1.6G左右(每次只取30-50M的数据量)
public class StartClass
{
/// <summary>
/// 该方法可能是个事件,在特定的条件下会执行
///数据量在1.6G左右(但每次只取30-50M的数据量)
/// </summary>
public void Main()
{
MyTest mt = new MyTest();
mt.StartMethod();
}
}public class MyTest
{
public void StartMethod()
{
//得到所有表的SQL数据脚本
List<string> _list = new List<string>();
//生成xml文件保存
XmlDocument xml = new XmlDocument();
//(省略...)
xml.Save("C:\\tmp.xml");
}
/// <summary>
/// 生成所有表的SQL数据脚本
/// </summary>
/// <returns></returns>
private List<string> GetList()
{
List<string> _list = new List<string>();
//得到所有表的名称
DataTable dt = this .GetAllTableName ();
//下面是得到一个表数据的全部SQL数据脚本
foreach (DataRow dr in dt.Rows)
{
//得到表名
string tableName = dr["tableName"].ToString();
DataTable dtData = this.GetTableData(tableName);
//下面是得到单行数据的SQL数据脚本
StringBuilder sb = new StringBuilder();
foreach (DataRow drData in dtData)
{
//这里可能会报"内存溢出";
sb.Append("insert into [表名]('字段名_1','字段名_2','字段名_3','字段名_N') values ('值_1','值_2','值_3','值_N');\r\n");
}
//将每个表的SQL数据脚本加到list中去
_list.Add(sb.ToString());
}
return _list;
}
/// <summary>
/// 得到所有合适表的名称
/// </summary>
/// <returns></returns>
private DataTable GetAllTableName()
{
DataTable dt = new DataTable();
return dt;
}
/// <summary>
/// 得到该表中的全部数据
/// </summary>
/// <param name="tableName"></param>
/// <returns></returns>
private DataTable GetTableData(string tableName)
{
DataTable dt = new DataTable();
return dt;
}
}祝:七七节快乐,送77分咯 *_*
详情如下:
引发类型为“System.OutOfMemoryException”的异常。
在 System.String.GetStringForStringBuilder(String value, Int32 startIndex, Int32 length, Int32 capacity)
在 System.Text.StringBuilder.GetNewString(String currentString, Int32 requiredLength)
在 System.Text.StringBuilder.Append(String value)原因:在调用下面的方法时,有时会产生上面的问题,有时则不会,可以保证的是每一次的数据量是不足于产生于溢出环境:
windows2003
CPU:4核,
内存:6G (运行时只使用不到3G内存),
SQL2005数据库。
取数的表数在1000左右,数据量在1.6G左右(每次只取30-50M的数据量)
public class StartClass
{
/// <summary>
/// 该方法可能是个事件,在特定的条件下会执行
///数据量在1.6G左右(但每次只取30-50M的数据量)
/// </summary>
public void Main()
{
MyTest mt = new MyTest();
mt.StartMethod();
}
}public class MyTest
{
public void StartMethod()
{
//得到所有表的SQL数据脚本
List<string> _list = new List<string>();
//生成xml文件保存
XmlDocument xml = new XmlDocument();
//(省略...)
xml.Save("C:\\tmp.xml");
}
/// <summary>
/// 生成所有表的SQL数据脚本
/// </summary>
/// <returns></returns>
private List<string> GetList()
{
List<string> _list = new List<string>();
//得到所有表的名称
DataTable dt = this .GetAllTableName ();
//下面是得到一个表数据的全部SQL数据脚本
foreach (DataRow dr in dt.Rows)
{
//得到表名
string tableName = dr["tableName"].ToString();
DataTable dtData = this.GetTableData(tableName);
//下面是得到单行数据的SQL数据脚本
StringBuilder sb = new StringBuilder();
foreach (DataRow drData in dtData)
{
//这里可能会报"内存溢出";
sb.Append("insert into [表名]('字段名_1','字段名_2','字段名_3','字段名_N') values ('值_1','值_2','值_3','值_N');\r\n");
}
//将每个表的SQL数据脚本加到list中去
_list.Add(sb.ToString());
}
return _list;
}
/// <summary>
/// 得到所有合适表的名称
/// </summary>
/// <returns></returns>
private DataTable GetAllTableName()
{
DataTable dt = new DataTable();
return dt;
}
/// <summary>
/// 得到该表中的全部数据
/// </summary>
/// <param name="tableName"></param>
/// <returns></returns>
private DataTable GetTableData(string tableName)
{
DataTable dt = new DataTable();
return dt;
}
}祝:七七节快乐,送77分咯 *_*
1、考虑将该句拆分为多句,以便更精确定位错误所在;
2、将出错时sb.ToString()的值记录,仔细研究有什么特点;
3、换其他表试试看;
4、换其他机器试试看。
是这样的,但是我每次只取了30-40G的数据量的(60W时间戳的内容)
所以每次的运行量不会超过2G的
Rows.Count是很多的,大概在60W-120W左右的
list.Add(sb.ToString());
在这里当使用完sb之后顺手加一行清除sb所有内容的语句,有点多余,不过多点保障,不妨试试,搞不好内存就不再益处了呢,呵呵.
2.单次运行的时候不会溢出。所以是不是这样子的:
1.stringBulider是在每次运行之后没有释放点原占有的内存?
2.是不是stringBulider是值copy 因为我可能要append在几十万次的 而导致错误..
这里的sb.Tostring()会不会有个问题
是在sb.Tostring()之后才清除sb啊,看不出问题.
{
//得到表名
string tableName = dr["tableName"].ToString();
DataTable dtData = this.GetTableData(tableName);
//下面是得到单行数据的SQL数据脚本
StringBuilder sb = new StringBuilder();
foreach (DataRow drData in dtData)
{
//这里可能会报"内存溢出";
sb.Append("insert into [表名]('字段名_1','字段名_2','字段名_3','字段名_N') values ('值_1','值_2','值_3','值_N');\r\n");
}
//将每个表的SQL数据脚本加到list中去
_list.Add(sb.ToString());
}
return _list;你用了大量StringBulder 实例,在return前调用垃圾收集器帮你清理下。System.GC.Collect();
这个初始化sb有长度限制的,如果你要加长的字符可以这样初始化
StringBuilder sb = new StringBuilder(10240);
这样sb的字符装载量有10240个,应该不会超了吧,根据实际长度来设置初始化的数值