艾伟_转载:DataTable.NewRow 内存泄漏问题

  昨天做了一个自动生成Insert 语句的小工具,今天测试发现存在严重的内存泄漏问题,代码看了好几遍,没发现问题。后来用 .Net Memory Profiler 跟踪(跟踪方法见 用 .NET Memory Profiler 跟踪.net 应用内存使用情况--基本应用篇) 发现有数千个DataRow 没有释放,最后定位是DataTable.NewRow 的问题。

  先看一下有问题的代码

public DataRow GetNextRow(){if (_DataReader.Read())    {        DataRow row = _SchemaTable.NewRow();foreach (DataColumn col in _SchemaTable.Columns)        {            row[col.ColumnName] = _DataReader[col.ColumnName];        }                return row;    }else    {return null;    }}

  这段代码我希望通过SqlDataReader 对象 _DataReader 来获取一行数据。_SchemaTable 是一个DataTable 对象,这个DataTable对象没有记录,只存放Table 的Schema。乍一看好像没有什么问题,_SchemaTable.NewRow() 是根据_SchemaTable 的列信息生成一个新行,但这个新行并没有调用 _SchemaTable.Rows.Add 方法加入到_SchemaTable 表中,一般认为这个新生成的 DataRow 在使用完后会被自动回收,但实际情况并不是这样,只要_SchemaTable 不释放,_SchemaTable.NewRow 生成的所有DataRow都无法释放。

  网上搜了一下,有一位仁兄和我遇到同样问题 Table NewRow() Causes Memory Leak

  被采纳的解决意见是这样的:

  DataTable.NewRow() adds the created row to the DataTable's RecordManager. I am not entirely sure why this happens, but this is why it is not freed by the GC.

  It appears that there are only two ways to get rid of the DataRow:

  1. Add it to the table, then delete it.
  2. Call DataTable.Clear().

  也就是说DataTable.NewRow 方法创建的DataRow 对象会被加入到DataTable 的 RecordManager 中,我们可以通过以下两种方法来释放掉它:

  1. 通过 DataTable.Rows.Add 方法将这一行加入到DataTable 中,然后再通过 DataTable.Rows.Remove 方法删除它。

  2. 调用 DataTable.Clear() 方法释放。

  由于我这个应用中数据表只存放架构信息,始终是空表,所有我采用了第2种方法。加入 _SchemaTable.Clear() 这一句后内存泄漏问题解决。

  改正后的代码如下:

public DataRow GetNextRow(){if (_DataReader.Read())    {        DataRow row = _SchemaTable.NewRow();foreach (DataColumn col in _SchemaTable.Columns)        {            row[col.ColumnName] = _DataReader[col.ColumnName];        }        _SchemaTable.Clear();return row;    }else    {return null;    }}

  不好意思,上面代码还是有问题, _SchemaTable.Clear() 后DataRow 里面的数据都会被清空,必须在调用完新生成的DataRow后再 _SchemaTable.Clear 才行,特此更正。

时间: 2024-09-27 14:13:46

艾伟_转载:DataTable.NewRow 内存泄漏问题的相关文章

DataTable.NewRow 内存泄漏问题

昨天做了一个自动生成Insert 语句的小工具,今天测试发现存在严重的内存泄漏问题,代码看了好几遍,没发现问题.后来用 .Net Memory Profiler 跟踪(跟踪方法见 用 .NET Memory Profiler 跟踪.net 应用内存使用情况--基本应用篇) 发现有数千个DataRow 没有释放,最后定位是DataTable.NewRow 的问题. 先看一下有问题的代码 public DataRow GetNextRow() { if (_DataReader.Read()) {

艾伟_转载:透视Datatable

源代码:/Files/zhuqil/PivotDataTable.zip  现在,以表格的形式显示的数据是任何应用程序的重要组成部分.但有时你需要以数据行格式显示大量的数据.如果行数巨大,它变得非常难以分析.在这种情况下,您可能希望使用其他格式统计你的数据,如: charts, graphs, groups, pivots等 .本文将介绍一种使用适当的聚合函数的方式来透视你的数据,它可以很容易提高您的报表功能. 下面的截图是在GridView中显示的数据透视功能.(关于数据透视还可以参考:ASP

艾伟_转载:数组排序方法的性能比较(上):注意事项及试验

昨天有朋友写了一篇文章,其中比较了List的Sort方法与LINQ中排序方法的性能,而最终得到的结果是"LINQ排序方法性能高于List.Sort方法".这个结果不禁让我很疑惑.因为List.Sort方法是改变容器内部元素的顺序,而LINQ排序后得到的是一个新的序列.假如两个排序方法的算法完全一致,LINQ排序也比对方多出元素复制的开销,为什么性能反而会高?如果LINQ排序的算法/实现更为优秀,那为什么.NET Fx不将List.Sort也一并优化一下呢?于是今天我也对这个问题进行了简

艾伟_转载:一次挂死(hang)的处理过程及经验

 前言:        CPU占用率低,内存还有许多空余,但网站无法响应,这就是网站挂死,通常也叫做hang.这种情况对于我这样既是CEO,又是CTO,还兼职扫地洗碗的个人站长来说根本就是家常便饭.以下是一次处理hang的经验及总结,前后用了一个月,不仅涉及程序排查,数据库优化,还有硬件升级的苦恼.其中辛酸苦辣只有经历过的站长才能体会,希望此文能对各位有所帮助!        首先介绍一下网站基本情况,是一个在线小说阅读网站,每天有一定页面访问量,在优化开始前由两台服务器运行,均为Dell Po

艾伟_转载:基于.NET平台的Windows编程实战(五)—— 问卷管理功能的实现

本系列文章导航 基于.NET平台的Windows编程实战(一)--前言 基于.NET平台的Windows编程实战(二)-- 需求分析与数据库设计 基于.NET平台的Windows编程实战(四)-- 数据库操作类的编写 基于.NET平台的Windows编程实战(五)-- 问卷管理功能的实现 基于.NET平台的Windows编程实战(六)-- 题目管理功能的实现 首先,为了使我们的界面更加便于操作及布局,我们引入第三开源控件DockPanel[当然也可以不引入控件而直接进行开发],你可以从这里:Do

艾伟_转载:ADO.NET中的五个主要对象

Connection 物件 Connection 对象主要是开启程序和数据库之间的连结.没有利用连结对象将数据库打开,是无法从数据库中取得数据的.这个物件在ADO.NET 的最底层,我们可以自己产生这个对象,或是由其它的对象自动产生. Command 物件 Command 对象主要可以用来对数据库发出一些指令,例如可以对数据库下达查询.新增.修改.删除数据等指令,以及呼叫存在数据库中的预存程序等.这个对象是架构在Connection 对象上,也就是Command 对象是透过连结到数据源 Data

艾伟_转载:老赵谈IL(3):IL可以看到的东西,其实大都也可以用C#来发现

在上一篇文章中,我们通过一些示例谈论了IL与CLR中的一些特性.IL与C#等高级语言的作用类似,主要用于表示程序的逻辑.由于它同样了解太多CLR中的高级特性,因此它在大部分情况下依旧无法展现出比那些高级语言更多的CLR细节.因此,如果您想要通过学习IL来了解CLR,那么这个过程很可能会"事倍功半".因此,从这个角度来说,老赵并不倾向于学习IL.不过严格说来,即使IL无法看出CLR的细节,也不足以说明"IL无用"--这里说"无用"自然有些夸张.但是

艾伟_转载:基于.NET平台的Windows编程实战(四)—— 数据库操作类的编写

本系列文章导航 基于.NET平台的Windows编程实战(一)--前言 基于.NET平台的Windows编程实战(二)-- 需求分析与数据库设计 基于.NET平台的Windows编程实战(四)-- 数据库操作类的编写 基于.NET平台的Windows编程实战(五)-- 问卷管理功能的实现 基于.NET平台的Windows编程实战(六)-- 题目管理功能的实现 大家都知道本系统的正常运行少不了数据库操作这一块,且其在本系统中具有决定性作用,可以说没有它的操作系统将无法运行,故在本节课程中,专门把针

艾伟_转载:C# Design Patterns (4) - Proxy

本帖介绍 Proxy Pattern (代理模式). Proxy Pattern (代理模式) The Proxy Pattern provides a surrogate or placeholder for another object to control access to it...                                  - Design Patterns: Elements of Reusable Object-Oriented Software 在 Go