在.NET DataTable中存储数据的内存开销是多少?
我试图得到一个与.NET数据表相关联的内存开销以及表中的单个DataRows的句柄。
换句话说,数据表占用的内存比仅仅存储每列数据的正确类型的数组所需的内存多多少?
我想会有一些基本的表开销,加上每列一些金额,然后再每行额外金额。因此,任何人都可以对这三种开销中的每一种/这些开销进行估计(以及我猜,解释!)。在.NET DataTable中存储数据的内存开销是多少?
那么,别忘了DataTable
店2? 3?数据的版本 - 原始和更新(可能是另一个?)。它也有很多参考,因为它是基于单元的,并且对任何值类型进行装箱。这将是难以量化的确切内存...
就个人而言,我很少使用DataTable
- 键入POCO类是一个更合理的赌注在我看来。我不会使用数组(直接),但 - List<T>
或BindingList<T>
或类似的会更常见。
作为一个粗略的衡量标准,你可以创建很多表格等,并查看内存使用情况;例如,下面显示了〜4.3因子 - 即4倍以上的昂贵的,但显然对列的数目取决于很多VS行VS表等:
// takes **roughly** 112Mb (taskman)
List<DataTable> tables = new List<DataTable>();
for (int j = 0; j < 5000; j++)
{
DataTable table = new DataTable("foo");
for (int i = 0; i < 10; i++)
{
table.Columns.Add("Col " + i, i % 2 == 0 ? typeof(int)
: typeof(string));
}
for (int i = 0; i < 100; i++)
{
table.Rows.Add(i, "a", i, "b", i, "c", i, "d", i, "e");
}
tables.Add(table);
}
Console.WriteLine("done");
Console.ReadLine();
VS
// takes **roughly** 26Mb (taskman)
List<List<Foo>> lists = new List<List<Foo>>(5000);
for (int j = 0; j < 5000; j++)
{
List<Foo> list = new List<Foo>(100);
for (int i = 0; i < 100; i++)
{
Foo foo = new Foo { Prop1 = "a", Prop3 = "b",
Prop5 = "c", Prop7 = "d", Prop9 = "e"};
foo.Prop0 = foo.Prop2 = foo.Prop4 = foo.Prop6 = foo.Prop8 = i;
list.Add(foo);
}
lists.Add(list);
}
Console.WriteLine("done");
Console.ReadLine();
(基于)
class Foo
{
public int Prop0 { get; set; }
public string Prop1 { get; set; }
public int Prop2 { get; set; }
public string Prop3 { get; set; }
public int Prop4 { get; set; }
public string Prop5 { get; set; }
public int Prop6 { get; set; }
public string Prop7 { get; set; }
public int Prop8 { get; set; }
public string Prop9 { get; set; }
}
如果您没有在列上定义索引,开销很低。如果使用字符串缓存,则可以获得相当低的内存占用空间: 使用HashSet或Dictionary仅使用每个字符串值的1个字符串实例。这听起来很奇怪,但是如果您从数据库中获取数据,并且您有多个具有相同字符串值的行(例如“ALFKI”),则字符串值相等,但字符串实例不是:字符串多次存储记忆。如果您首先使用HashSet过滤出重复实例,则可以在数据表中的任意位置为1个字符串值有效使用相同的字符串实例。这可以大大减少内存占用。当然,如果字符串值已经在某个地方被静态定义(所以不能从外部源读取),这是不值得的。
这取决于您要存储多少数据和哪种数据。显然数据越多,内存越多。有一些与数据表有关的开销,这使得它更加昂贵。您还需要了解大对象堆。如果您存储超过85 kb的对象,则该对象将存储在LOH中。这可能会对垃圾收集造成严重破坏,因为它需要完整的收集。如果您准备测试它,请查看内存分析器以观察数据表的内存占用情况。
@Marc - 包含参考文献无损AcceptChanges和朋友可以用来操纵正在存储的版本库存。 @Nick:底线是如果你想要光线,DataX不是你不想看的地方,而且你甚至不需要去测量。 为什么不写一些测试来衡量? – 2009-01-08 15:29:06
@Ruben - 处理它;-p – 2009-01-08 15:38:11
Marc DataTable不包含值,它将类型数组中的值类型存储起来。 – 2009-01-08 15:43:11