当前位置:   article > 正文

tomcat如何部署.net程序_如何找出 .NET 程序中的数据库连接泄漏

reader.getblockcontrolobject()

通常我们可以通过查看性能计数器 NumberOfReclaimedConnections 来观察是否存在数据库连接泄露的问题,通常对应于 .NET Data Provider for Oracle 和 .NET Data Provider for SqlServer下,如下图:

 fbb37f9e5632d8891e8855890ce9c51b.png

如果通过性能计数器 NumberOfReclaimedConnections 观察到有数据库连接泄露的问题,我们通常可以通过 Code Review ,找出泄漏点。但是如果代码量很大,此时很难通过直接 Code Review 的方式来定位。这时候我们可以通过抓取 DUMP 来定位出可能存在泄露的数据库语句,然后通过数据库语句定位可能的泄漏点,然后再通过 Code Review 的方式找出未关闭连接的代码并解决即可。

通常查看数据库连接泄露的 DUMP 可以通过以下几步定位:

  1. 查看 DUMP 中的性能计数器:

  • 如果是 SQL 则通过命令 !mex.sqlclientperfcounters 获取;

  • 如果是 Oracle 则通过命令 !mex.oracleclientperfcounters 获取;

查看可能存在泄露的 SQL 命令:!mex.sqlcmd -l

125afa613b81aa1590d79e17a152cf3c.png

根据上面获得的命令定位泄漏点:

  • 此时如果我们有对应的工程,则可以在工程中尝试搜索这些 SQL Command 或者存储过程在哪些地方被使用,并定位出问题点;

  • 如果没有工程,在反编译工具中无法进行全局搜索,因此可以在 DUMP 中通过 GC Root 尝试恢复出调用栈,然后根据线索找出泄漏点;

常见的数据库泄露问题代码样式:

  • 关闭连接部分代码放在 finally 代码块中;此时如果执行过程中出现异常,则无法正常关闭连接;

  • 在 ExecuteReader 中指定行为常量为 CommandBehavior.CloseConnection,但最终未关闭 DataReader 对象;

  • 在类中定义的静态数据库连接变量用于连接复用,此时需要注意在合适的时候关闭连接,否则该连接很可能一直无法释放;

Notes:

我们也可以使用 netext 插件,获取所有数据库连接状态:

!netext.windex;#Oracle Connection:!wfrom -type Oracle.DataAccess.Client.OracleConnection select $a("Address: ",$addr()),$a("State:",$fieldaddress(m_state))MSSQL Connection:!wfrom -type System.Data.SqlClient. SqlConnection  select $a("Address: ",$addr()),$a("State:",$fieldaddress(m_state))#以下方法可以列出所有未关闭的连接:!netext.windex;#Oracle Connection:!wfrom -type Oracle.DataAccess.Client.OracleConnection where(m_state) select $a("Address: ",$addr()),$a("State:",$fieldaddress(m_state))#MSSQL Connection:!wfrom -type System.Data.SqlClient. SqlConnection  where(m_state)  select $a("Address: ",$addr()),$a("State:",$fieldaddress(m_state))

文档信息

  • 本文作者:Robin Chen

  • 本文链接:https://crushonme.github.io/2018/06/07/How-To-Find-Out-SQL-Connection-Leak/

  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
  

闽ICP备14008679号