【问题标题】:SQL server and .NET memory constraints, allocations, and garbage collectionSQL Server 和 .NET 内存约束、分配和垃圾回收
【发布时间】:2012-05-29 12:51:28
【问题描述】:

我正在运行 .NET 3.5 (C#) 和 SQL Server 2005(针对我们的客户)。我们运行的代码做了一些回归数学,有点复杂。当我在我们的网站上运行多个页面时出现以下错误:

.NET Framework execution was aborted by escalation policy because of out of memory. 
System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.
System.InvalidOperationException: 

我试图找出造成这种情况的根本原因:是数据库问题还是我的 C## 代码?还是在运行查询时与锁并发?还是别的什么?

这里的代码出错了:

erver.ScriptTimeout = 300;
        string returnCode = string.Empty;
        using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MainDll"].ToString())) {
            connection.Open();
            using (SqlCommand command = new SqlCommand(sql.ToString(), connection)) {
                command.CommandType = CommandType.Text;
                command.CommandTimeout = 300;
                returnCode = (string)command.ExecuteScalar();
                //Dispose();
            }
            //Dispose();
        }

我们的承包商在 App_Code/sqlHelper.s 文件中编写了一堆代码来帮助处理 SQL 连接。其中一些是这样的:

public static SqlDataReader GetDataReader(string sql, string connectionString, int connectionTime) {
        lock (_lock) {
            SqlConnection connection = null;
            try {
                connection = GetConnection(connectionString);
                //connection.Open();
                using (SqlCommand cmd = new SqlCommand(sql, connection)) {
                    cmd.CommandTimeout = connectionTime;
                    WriteDebugInfo("GetDataReader", sql);
                    return cmd.ExecuteReader(CommandBehavior.CloseConnection);
                }
            }
            catch (Exception e) {
                if (connection != null)
                    connection.Dispose();
                throw new DataException(sql, connectionString, e);
            }

        }
    }

是否应该在某处释放一些内存?

【问题讨论】:

  • 你要关闭你的连接吗?
  • 请提供您的代码,以便大家查看。
  • 刚刚注意到 dispose 也被注释掉了
  • 寻找对 ExecuteReader 的调用。问题不在此代码中。
  • 为什么SqlDataReader中有锁对象?我看不出有什么原因,这一切看起来都是线程安全的。事实上,这只会杀死并发 AFAIK,尤其是在长时间运行的查询中。 GetConnection 有什么作用?

标签: c# asp.net .net sql-server sql-server-2005


【解决方案1】:

问题在于,由于某种原因,您的 DataReader 没有被关闭。例外?用户不记得关闭 DataReader 的方法?

返回要在其主体外部使用的 DataReader 的函数将关闭它的责任留给外部代码,因此无法保证 Reader 将被关闭。如果不关闭阅读器,则无法重用打开阅读器的连接。

所以从函数返回 DataReader 是一个非常糟糕的主意!

你可以看到关于这个主题的完整讨论here

寻找这个函数的用法(GetDataReader),并检查是否保证阅读器正在关闭。而且,最重要的是,这段代码不可能在第一个关闭之前重新进入并使用同一个集合打开一个新的 DataReader。 (不要被 CommandBehavior.CloseConnection 误导。这只会在 DataReader 关闭时关闭连接......只有在您没有关闭它的情况下)

【讨论】:

    【解决方案2】:

    这是因为你的数据读取器已经填好了。在 finally 块中释放数据读取器、命令、数据集、数据表并关闭连接总是更好的方法。 利用 Dispose() 和 Close() 方法。

    【讨论】:

      猜你喜欢
      • 2012-04-08
      • 1970-01-01
      • 1970-01-01
      • 2012-04-11
      • 1970-01-01
      • 2015-11-13
      • 1970-01-01
      • 1970-01-01
      • 2017-03-15
      相关资源
      最近更新 更多