.NET对象的内存开销是多少?

53

在.NET中,一个对象的内存开销是多少?我所说的是任意裸对象....即.NET内部工作或引用的开销:

var obj = new System.Object();

obj在堆中占用多少空间?


1
堆和栈是实现细节。 - asawyer
3
@ThePower:不是重复的问题。那个问题(以及其中的答案)根本没有讨论.NET对象的基本内存开销。 - Robert Harvey
2
@ThePower 这并没有回答我的问题,我想知道内存开销,而不是如何测量它。 - reach4thelasers
3
@asawyer - 你能解释一下你的评论吗?我认为堆是一种抽象数据结构,其中存储了所有对象... 为什么询问“它在堆中占用多少空间”是错误的?为什么询问“它在堆中占用多少空间”是错误的?这个问题存在歧义,因为“堆”一词可以同时指代计算机科学中的抽象数据结构和内存管理中的实际物理部分。在前者中,“堆”只是一种数据结构,不占据任何特定的内存空间;而在后者中,“堆”是一个由操作系统分配和管理的内存区域,可以占用实际物理内存。因此,在询问关于对象在堆中占用多少空间时,需要明确是指物理内存中的堆还是抽象数据结构中的堆。 - reach4thelasers
3
“你可以使用类似.NET Memory Profiler的内存分析器来回答我的问题?” - reach4thelasers
显示剩余2条评论
1个回答

62

我在一篇博客文章中谈到了这个问题:"内存和字符串"。 这是具体实现相关的,但对于微软.NET CLR v4而言,x86 CLR每个对象的开销为8字节,x64 CLR每个对象的开销为16字节。

然而,它们至少需要12和24个字节 - 只是当你开始存储有用信息时,你会“免费”获得前4或8个字节 :)

(请参见博客文章以获取更多信息。)


2
成员变量可能会有填充以适应地址边界。这种填充概念进一步复杂化了对象内存开销的计算。难怪C#从未为类型的实例变量引入sizeof运算符。 - RBT
1
我在一个 .net 控制台应用程序中运行了几个测试以检查内存使用情况。创建 1000 万个空对象导致大约 340MB 的使用量(包括引用列表)。向类中添加 1 或 2 个整数没有改变任何东西。只有当添加第三个整数时,我才看到增加到大约 430MB。这完全支持您的最小 24 字节的陈述,其中 8 字节用于信息。 - JohnF
1
嗨@JonSkeet,您能为“内存开销”添加一个通用定义吗?我真的不明白它是什么。这就像为每个对象分配额外的内存?谢谢。 - BorisD
1
@BorisD:是的——它是除了数据本身所需的“显而易见”的内存之外所需的内存。(清理信息等) - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接