列出<object []>使用比DataTable更多的内存?

Ste*_*eve 5 c# datatable ado.net

我一直认为DataTable会消耗比通用List更多的内存.我正在测试加载DataTable并从SQL Server查询加载List.在这种情况下,DataTable消耗的内存较少.我得到了前2000行,每行有134个字段.一个二进制字段,其余为标准varchar,int,bit等.

在这个世界上,如果DataTable的所有开销都比List少,那么它的内存消耗量是多少?GC使用DataTable报告大约4mb,使用列表报告5mb.

我测试了一些NorthWind表,在这些情况下列表略小.

private void GetMemory()
    {
        label1.Text = string.Format("{0:0.00} MB", GC.GetTotalMemory(true) / 1024.0 / 1024.0);            
    }
    private void DataTableButton_Click(object sender, EventArgs e)
    {
        var conn = new SqlConnection(@"Initial Catalog=ADatabase;Data Source=AServer;Integrated Security=True");
        conn.Open();

        var cmd = new SqlCommand("SELECT TOP 2000 * FROM AManyColumnedTable", conn);

        var r = cmd.ExecuteReader();
        _rows = new List<object[]>();

        //uses more memory
        object[] a = null;
        while (r.Read())
        {
            a = new object[r.FieldCount];
            r.GetValues(a);
            _rows.Add(a);
        }
        //uses less memory
        //_table = new DataTable("TheTable");
        //_table.Load(r);

        r.Close();
        conn.Close();
        GetMemory();
    }
Run Code Online (Sandbox Code Playgroud)

Guf*_*ffa 6

这是一种错觉。不知何故,GC 没有给你正确的值,也许是因为有些对象还没有被收集。也许加载一个数据表会导致更多的中间对象,这会导致另一个垃圾收集。

您的数组列表以与数据表相同的方式存储数据,但没有数据表和每个数据行包含的额外信息的开销。

如果您希望它具有更高的内存效率,您应该为数据记录创建一个类,这样您就可以将值类型存储为普通值而不是装箱在对象中。例如,一个 int 在装箱时使用 20 个字节,但只有 4 个作为普通成员变量。