由于数据表的回发,内存峰值过多

时间:2014-12-23 13:12:53

标签: c# .net memory-management memory-leaks datatable

我基本上有一个包含邮政编码区域的列表框,例如:AE,CW,GU等等。

用户选择此项,然后发生回发 - 构建sql语句并执行数据库查询操作,并将结果返回到名为tempdata的数据表中。

到目前为止一切顺利。然后我需要遍历这个数据表并将记录复制到我的主viewstate数据表,这是google maps api的数据源。

  DataTable tempstore = GetData(querystring, "");

                        //check tempstore has rows otherwise add defaultcust as default otherwise map will be blank

                        if (tempstore.Rows.Count == 0)
                        {
                            tempstore = GetData("WHERE CUSTCODE=='CD344'", "");

                            infoalert.Visible = true;

                            infoalert.InnerHtml = "No Results Returned For Selection";
                        }

                        foreach (DataRow row in tempstore.Rows)
                        {

                            dtpc.ImportRow(row);
                            dtpc.AcceptChanges();

                        }

        //database command
 using (OleDbConnection con = new OleDbConnection(conString))
            {
                using (OleDbCommand cmd = new OleDbCommand(query))
                {
                    using (OleDbDataAdapter sda = new OleDbDataAdapter())
                    {
                        cmd.Connection = con;

                        sda.SelectCommand = cmd;

                        sda.Fill(dt5);

                    }
                }
            }    

因此,当用户添加更多邮政编码时,我的主数据表可以增长和增长。然而,当它达到大约500行左右时,我只在回发时得到一个巨大的内存峰值,然后它稳定下来。我的ram使用率从2gb变为3gb,如果选择更多的邮政编码,它会占用内存并使我的电脑崩溃。

如果我删除了:

dtpc.Importrow(row);

内存峰值完全消失,显然是因为主数据表没有行。我认为当你有数千行时,你只会遇到内存问题?

非常感谢任何帮助。

谢谢

2 个答案:

答案 0 :(得分:0)

你真的需要一次性所有行吗? DataReader将一次访问一行并将内存保持在最低值 DataReader class

如果您需要一次性获取所有数据,请为数据创建一个strut类,并将其保存在List之类的集合中。 DataTable是一个沉重的对象。

如果您通过任务管理器测量内存,请注意它不是很准确。

答案 1 :(得分:0)

首先,请确保在适当的“using”子句中包装任何SQL执行。这很可能是导致问题的原因。

using (var command = new SqlCommand())
{
    // Some code here
}
像Blam说的那样,DataTable太重了你的目的。

您可以非常轻松地将数据行转换为类对象:

var datasourceList = new List<YourCustomObject>();

foreach (DataRow row in tempstore.Rows)
{
    var newMapsObject = new YourCustomObject
    {
        Value1 = row.Field<String>("Value1ColumnName"),
        Value2 = row.Field<String>("Value2ColumnName")
    };

    datasourceList.Add(newMapsObject);
}

viewStateList.AddRange(datasourceList);

要将自定义集合绑定到数据显示(例如转发器),请将列表分配给所述显示的.DataSource属性,然后调用.DataBind()。这适用于大多数所有ASP.NET数据显示对象。

repeater1.DataSource = viewStateList;
repeater1.DataBind();