【问题标题】:SQL handle leak on .Net 4.0 but not on .Net 3.5.Net 4.0 上的 SQL 句柄泄漏,但 .Net 3.5 上没有
【发布时间】:2013-08-19 02:51:28
【问题描述】:

以下示例代码泄漏句柄。句柄数从 133 开始,不到 2 小时就达到了 900。示例是 VS2010 和 .Net 4.0。这不会发生在 .Net 3.5 上。 我已经在超过 3 台机器上复制了这个,所有的 Win2008 R2 服务器。 SQL 2008 和 SQL 2012。这些机器是虚拟机,每周不断回滚两次,所以很干净。

//Reference dll are the ones required for SQL 
//.Net 4.0 (not 'Client Profile' version)
static void Main(string[] args)
{

    string sss = "Data Source=WIN-0BDHQ0IIUFL,1433;Initial Catalog=DB_Mycentral;Persist Security Info=False;User ID=Myuser;Password=123;Connect Timeout=60;Network Library=dbmssocn";
    System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(sss);
    int i = 0;
    while (true)
    {
        i++;

        Thread.Sleep(1000 * 60 * 60);
        Console.WriteLine("{0} hrs sleep", i);
    }
}

我观察到 ProcMon.exe 中的活动和 ProcExp.exe 中的调用堆栈。 ProcMon.exe 重复记录了 CreateThread() 和 ExitThread()。然后 ProcExp.exe 显示 cld.dll!StrongNameErrorInfo+0​​x18910 针对新创建的 TID。最后,ProcExp.exe 中的 THREAD 对象计数增加了一个。这整个过程一次又一次地重复。

Example for leaking of TID 9089:
CreateThread()/ExitThread() TID:9089 //Log in ProcMon.exe
cld.dll!StrongNameErrorInfo+0x18910  TID: 9089  //Call-stack in ProcExp.exe

背景:我编写此示例是为了缩小生产代码中的漏洞。该代码在 .Net 3.5 中运行良好,但在 .Net 4.0 中泄漏。

如果我必须在打开连接时设置额外的标志,请告诉我。

【问题讨论】:

  • 你依赖终结器(因为你没有处理),所以除非垃圾收集器运行,否则你不会被终结。 dotnettips.wordpress.com/2011/10/24/…
  • 考虑到编写问题所花费的时间,谷歌搜索 SqlConnection Leak Handle 会更好......它似乎很有名。这说明当你有问题时,首先google。
  • 谢谢科普。我会尝试MS建议的解决方案。
  • 显示的代码只打开一个连接。它不应该泄漏。以前的 cmets 不应该适用。
  • Usr2:是的,它只打开连接但仍然泄漏。在几台机器上验证。

标签: sql .net-4.0 .net-3.5 resource-leak


【解决方案1】:

使用“使用”确保始终调用 dispose 方法。

http://msdn.microsoft.com/en-us/library/yh598w02.aspx

//Reference dll are the ones required for SQL 
//.Net 4.0 (not 'Client Profile' version)
static void Main(string[] args)
{

    string sss = "Data Source=WIN-0BDHQ0IIUFL,1433;Initial Catalog=DB_Mycentral;Persist Security Info=False;User ID=Myuser;Password=123;Connect Timeout=60;Network Library=dbmssocn";
    using(System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(sss))
    {

        int i = 0;
        while (true)
        {
            i++;

            Thread.Sleep(1000 * 60 * 60);
            Console.WriteLine("{0} hrs sleep", i);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    • 2015-03-15
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    相关资源
    最近更新 更多