【发布时间】:2016-03-20 05:33:41
【问题描述】:
我一直理解结构(值类型)包含的字节数与结构字段中定义的字节数完全相同……但是,我做了一些测试,空结构似乎有一个例外:
public class EmptyStructTest
{
static void Main(string[] args)
{
FindMemoryLoad<FooStruct>((id) => new FooStruct());
FindMemoryLoad<Bar<FooStruct>>((id) => new Bar<FooStruct>(id));
FindMemoryLoad<Bar<int>>((id) => new Bar<int>(id));
FindMemoryLoad<int>((id) => id);
Console.ReadLine();
}
private static void FindMemoryLoad<T>(Func<int, T> creator) where T : new()
{
GC.Collect(GC.MaxGeneration);
GC.WaitForFullGCComplete();
Thread.MemoryBarrier();
long start = GC.GetTotalMemory(true);
T[] ids = new T[10000];
for (int i = 0; i < ids.Length; ++i)
{
ids[i] = creator(i);
}
long end = GC.GetTotalMemory(true);
GC.Collect(GC.MaxGeneration);
GC.WaitForFullGCComplete();
Thread.MemoryBarrier();
Console.WriteLine("{0} {1}", ((double)end-start) / 10000.0, ids.Length);
}
public struct FooStruct { }
public struct Bar<T> where T : struct
{
public Bar(int id) { value = id; thing = default(T); }
public int value;
public T thing;
}
}
如果你运行程序,你会发现 en FooStruct 显然有 0 个字节的数据会消耗 1 个字节的内存。这对我来说是个问题的原因是我希望 Bar<FooStruct> 正好消耗 4 个字节(因为我要分配很多)。
为什么它会有这种行为,有没有办法解决这个问题(例如,有没有消耗 0 字节的特殊东西——我不是在寻找重新设计)?
【问题讨论】:
-
P.S.:[StructLayout(LayoutKind.Explicit, Size=0)] 给出相同的结果。
-
GC.GetTotalMemory 准确吗?如果是这样,我在内存分析器上浪费了钱。
-
为什么不直接跳过 Bar 并让 FooStruct 包含公共 int 值?
-
允许值有 0 个字节会创建一种吞噬黑洞的奇点。由于数组是一个明显的受害者,它的所有元素都将具有相同的地址。不要使用极端情况进行测试,而是针对您关心的结构进行测试。
标签: c# .net generics memory-management value-type