先看一下有问题的代码 public DataRow GetNextRow() { if (_DataReaderRead()) { DataRow row = _SchemaTableNewRow(); foreach (DataColumn col in _SchemaTableColumns) { row[colColumnName] = _DataReader[colColumnName]; } return row; } else { return null; } } 这段代码我希望通过SqlDataReader 对象 _DataReader 来获取一行数据_SchemaTable 是一个DataTable 对象这个DataTable对象没有记录只存放Table 的Schema乍一看好像没有什么问题_SchemaTableNewRow() 是根据_SchemaTable 的列信息生成一个新行但这个新行并没有调用 _SchemaTableRowsAdd 方法加入到_SchemaTable 表中一般认为这个新生成的 DataRow 在使用完后会被自动回收但实际情况并不是这样只要_SchemaTable 不释放_SchemaTableNewRow 生成的所有DataRow都无法释放 网上搜了一下有一位仁兄和我遇到同样问题 Table NewRow() Causes Memory Leak 被采纳的解决意见是这样的 DataTableNewRow() adds the created row to the DataTables 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: Add it to the table then delete it Call DataTableClear() 也就是说DataTableNewRow 方法创建的DataRow 对象会被加入到DataTable 的 RecordManager 中我们可以通过以下两种方法来释放掉它 通过 DataTableRowsAdd 方法将这一行加入到DataTable 中然后再通过 DataTableRowsRemove 方法删除它 调用 DataTableClear() 方法释放 由于我这个应用中数据表只存放架构信息始终是空表所有我采用了第种方法加入 _SchemaTableClear() 这一句后内存洩漏问题解决 改正后的代码如下 public DataRow GetNextRow() { if (_DataReaderRead()) { DataRow row = _SchemaTableNewRow(); foreach (DataColumn col in _SchemaTableColumns) { row[colColumnName] = _DataReader[colColumnName]; } _SchemaTableClear(); return row; } else { return null; } } 不好意思上面代码还是有问题 _SchemaTableClear() 后DataRow 里面的数据都会被清空必须在调用完新生成的DataRow后再 _SchemaTableClear 才行特此更正 |