【发布时间】:2012-02-12 10:35:48
【问题描述】:
我将拥有数千万个 MyClass 类的实例,并希望最小化它的内存大小。在Find out the size of a .net object 中讨论了测量对象在内存中占用多少空间的问题。 我决定听从 Jon Skeet 的建议,这是我的代码:
// Edit: This line is "dangerous and foolish" :-)
// (However, commenting it does not change the result)
// [StructLayout(LayoutKind.Sequential, Pack = 1)]
public class MyClass
{
public bool isit;
public MyClass nextRight;
public MyClass nextDown;
}
class Program
{
static void Main(string[] args)
{
var a1 = new MyClass(); //to prevent JIT code mangling the result (Skeet)
var before = GC.GetTotalMemory(true);
MyClass[] arr = new MyClass[10000];
for (int i = 0; i < 10000; i++)
arr[i] = new MyClass();
var after = GC.GetTotalMemory(true);
var per = (after - before) / 10000.0;
Console.WriteLine("Before: {0} After: {1} Per: {2}", before, after, per);
Console.ReadLine();
}
}
我在 64 位 Windows 上运行该程序,选择“发布”,平台目标:“任何 cpu”,然后选择“优化代码”(这些选项仅在我明确针对 x86 时才重要)结果遗憾的是 48 字节每个实例。
我的计算将是每个引用 8 个字节,加上 1 个用于 bool 的字节加上大约 8 个字节的开销。到底是怎么回事?这是一个让 RAM 价格居高不下和/或让非 Microsoft 代码膨胀的阴谋吗?好吧,好吧,我想我真正的问题是:我做错了什么,或者我怎样才能最小化 MyClass 的大小?
编辑:我为我的问题草率道歉,我编辑了几个标识符名称。我具体而直接的关注是构建一个“2-dim 链表”作为稀疏布尔矩阵实现,我可以在其中轻松获取给定行/列中设置值的枚举。 [当然这意味着我还必须在类中存储 x,y 坐标,这让我的想法更加不可行]
【问题讨论】:
-
等等,你是在一个字节的边界上打包并且你有一个一个字节的结构在一堆引用之前? 您知道这是多么危险和愚蠢吗? 许多架构上运行时的性能和正确性取决于指针是否正确对齐!特别是易失性和原子性语义完全取决于对齐是否正确。如果运行时实际上是按照您的说明进行操作并将这些指针错位一个字节,那么您将遇到大问题。
-
我认为我们必须查看您的
MyClass代码才能帮助解决该问题。 -
Lippert 先生,不,我不知道,请纠正我,我不在乎布局,我只是想缩小尺寸。
-
@AllenG :这几乎是实现,除了会有属性而不是字段。我正在尝试使用“二维链表”实现稀疏布尔矩阵的想法。
-
只有将它们放在数组中并且它们是值类型时才会节省空间。他们仍然会遇到@EricLippert 指出的问题,甚至可能更多。当然,将它们自己的类型作为字段引用是行不通的。
标签: c# memory-management