DataTable内存消耗巨大

本文关键字:巨大 内存 DataTable | 更新日期: 2023-09-27 18:29:08

我正在将csv数据从文件加载到数据表中进行处理。

问题是,我想处理几个文件,而我对数据表的测试显示了巨大的内存消耗我用一个37MB的csv文件进行了测试,内存增长到240MB,这相当于IMHO。我读到,数据表中有开销,我可以使用大约70MB的大小,但不能使用240MB,这意味着它是原始大小的六倍。我在这里读到,数据表比POCO需要更多的内存,但区别太大了。

我安装了一个内存探查器,查看是否存在内存泄漏以及内存在哪里。我发现,datatablecolumns中有6MB到19MB的字符串,datatable中大约有20列。值是否存储在列中?为什么占用了这么多内存,我能做些什么来减少内存消耗。由于内存消耗,数据附件似乎无法使用。

是否有其他人对数据表有这样的问题,或者我做错了什么?

PS:我尝试了一个70MB的文件,数据表增长到了500MB!

好的,这里是一个小的测试用例:37MB的csv文件(21列)使内存增加到179MB。

    private static DataTable ReadCsv()
    {
        DataTable table = new DataTable();
        table.BeginLoadData();
        using (var reader = new StreamReader(File.OpenRead(@"C:'Develop'Tests'csv-Data'testdaten'test.csv")))
        {               
            int y = 0;
            int columnsCount = 0;
            while (!reader.EndOfStream)
            {
                var line = reader.ReadLine();
                var values = line.Split(',');
                if (y == 0)
                {
                    columnsCount = values.Count();
                    // create columns
                    for (int x = 0; x < columnsCount; x++)
                    {
                        table.Columns.Add(new DataColumn(values[x], typeof(string)));
                    }
                }
                else
                {
                    if (values.Length == columnsCount)
                    {
                        // add the data
                        table.Rows.Add(values);
                    }
                }
                y++;
            }
            table.EndLoadData();
            table.AcceptChanges();
        }
        return table;
    }

DataTable内存消耗巨大

DataSet及其子级DataTableDataRow等组成内存中的关系数据库。这涉及到很多开销(尽管它确实让[一些]事情变得非常方便

如果内存有问题,

  • 构建域对象,用键入的属性表示CSV文件中的每一行
  • 创建一个自定义集合(或者只使用IList<T>来保存它们
  • 或者,使用DataTable的基本语义构建一个轻量级类:
    • 按数字选择行的能力
    • 能够逐行选择一行中的一列,也可以选择列名或编号
    • 了解有序列名集的能力
    • 附加功能:能够按名称或序号选择列,并接收其值列表,每行一个

您确定需要CSV文件的内存表示形式吗?你能像Sebastien Lorion的快速CSV阅读器一样通过IDataReader访问它们吗?

DataTables是将表格数据放入内存并添加许多与表相关的功能的通用解决方案。如果开销对您来说是不可接受的,您可以选择1)编写自己的DataTable类,以消除不需要的开销2)使用仍然可以完成所需内容的替代表示,可能是基于POCO的,也可能是XMLDocument(可能有同样多的开销,可能更多,从来没有真正担心过)。3) 不要试图将所有内容加载到内存中,只需根据需要从外部存储中引入数据即可。