c# object占多少字节

Object tem = new Object();tem占多少字节?64位和32位机器的区别呢?
int i;这时候i占多大内存?
ClassA a;a占多大呢?
pztx1992:

你没有理解我说的意思,,
假如:class A{string str;public string Str(get{return str;}set{str = value;})} A a = new A();str在a中也要占空间.这样占多大?你如果new了的话,其实也是算是赋了初值的..你不知道string类型的默认值是string.empty吗?int的是0吗?不是一定要a.Str="123";才算赋初值;

Object占多少内存,谁也不知道,按照非托管的想法是,如果你只定义一个类,而它没有任何数据成员,我在VS2008下,使用默认字节对齐,
class Object
{

};
这样得出来 sizeof( Object ) 为 1。

在C#里,是不能直接获取object占用内存大小的,因为它根本不是一个标准的布局。
而楼上的BinaryFormatter的方法,只是以二进制格式将对象或整个连接对象图形序列化和反序列化。它甚至还有可能包含版本信息,所以它的结果并不能代表一个对象所占用内存的大小。
C#提供了一种可以获取一个对象的非托管内存的大小的方法。但是必须在显式指定了内存布局以及字节对齐等信息的对象上才可以使用。

现在我们定义如下对象:
[StructLayout( LayoutKind.Sequential )]
public class MyObject
{
}
,大家都知道,所有的对象都是从MyObject继承而来的,也就是说,我们上面这个MyObject类,也隐含的继承了Object。
那么,现在我们看看这段代码:
int size = Marshal.SizeOf( typeof( MyObject ) );
运行结果是1。
看来跟C++是一样的。也就是说,一个未定义任何数据成员的空对象,其占用1字节的内存。

那么我们再来看看一些标准成员的大小,比如int,long,double等。
int size = Marshal.SizeOf( typeof( int ) ); //结果为4
int size = Marshal.SizeOf( typeof( long ) ); //结果为8
int size = Marshal.SizeOf( typeof( float ) ); //结果为4
int size = Marshal.SizeOf( typeof( double ) ); //结果为8
可见,这些基本数据类型,与非托管下的大小是没有区别的。

那么现在我们来看看混合在一起的情况。
[StructLayout( LayoutKind.Sequential )]
public class MyDataObject
{
public byte a;
public int x;
public Char b;
public double c;
}
然后我们执行 int size = Marshal.SizeOf( typeof( MyDataObject ) );
会发现结果是24。
为什么是24呢,是因为我们指定了LayoutKind.Sequential,它的MSDN的说明如下:
对象的成员按照它们在被导出到非托管内存时出现的顺序依次布局。这些成员根据在 System.Runtime.InteropServices.StructLayoutAttribute.Pack中指定的封装进行布局,并且可以是不连续的。

那么,MyOjbect 的大小实际上就是所有数据成员内存字节对齐后然后结构体的大小。
则VS2008上,字节对齐(即StructLayoutAttribute.Pack)默认设置好像是8。
下面是MyDataObject对象在默认设置下的对齐情况:
成员 偏移位置(字节) 内存分布(字节)
a 0 0
x 4 4-7
b 8 8
c 16 16-23
总长度为24
现在我们来看字节对齐为4的情况:
成员 偏移位置(字节) 内存分布(字节)
a 0 0
x 4 4-7
b 8 8
c 16 12-19
总长度为20。
字节对齐为2的情况:
成员 偏移位置(字节) 内存分布(字节)
a 0 0
x 4 2-5
b 8 6
c 16 8-16
总长度为16。
字节对齐为1的情况:这就是最紧凑的情况了。
成员 偏移位置(字节) 内存分布(字节)
a 0 0
x 4 1-4
b 8 5
c 16 6-13
总长度为14。

总体上来说,.net的对象占用的空间,跟其它非托管程序是一样的,只是大部分的对象,由于是托管的,而且没有规定内存布局,所以我们无法获得其真正占用内存的大小。

PS:
StructLayoutAttribute类和Marshal类位于命名空间“System.Runtime.InteropServices”下。

本来上面的对齐的排列顺序,我写的的时候中间有好几个空格的,不知道为什么发上来就成一个空格了,排版不好看了,效应着看吧,呵呵

//------------我也来更新一下,不知道你们两个人在争什么?
.net是中间语言,什么叫做托管?托管的主要意思就是它把内存控制权接管了,简之,你所写的代码并不是像C/C++那样对内存的精确控制。

就拿C#来说,它是号称没有指针,但是,实际上大家都看得出来,它的所谓引用型参数,就是指针。为什么这么说?你试试调用一个非托管的API,如果那个参数是指针类型的话,那你就得用ref了。

就拿你的问题ClassA a来说,现在我们就假定.net内部是指针,那么
ClassA a,就相当于是定义了一个指针,我们知道,指针在32位系统下,占4字节。当然,这里还有一个前提,就是ClassA是一个class,不是struct或者其它值类型。

至于string类型的成员的占用内存的大小,不知道楼主你会不会C++,有没有见过std的string是怎么实现的?为了提交效率,降低内存分配频率,string对象在创建时,就会默认了一个容量长度,这个跟它存储的字符串长度是不一样的,如果存储的字符串长度超过了容量,那么它会再重新分配一块更大的内存来存储。但目前我还没看到.net的String对象的源代码,所以不知道它的默认容量是多大,那个就应该是它默认占的内存大小。我只知道StringBuilder的默认容量是16,我想string的也许更大些吧。

末了,不知道你们讨论一个托管对象的占用内存大小还有什么意义。
我想你以为我这么在一段,是哪里COPY来吧,不好意思,我没有COPY别人答案的习惯,全是手敲的,有空的就把我的话,当废话看吧,我也没什么成见,就发表个人观点而已。
该回家吃饭了,各位,再会,
温馨提示:答案为网友推荐,仅供参考
第1个回答  2008-10-30
我问的是没有new占多大空间
你觉得测试没有new的对象有意义吗?其结果我想你也知道,不分配任何空间,不占用字节
没有new的对象,内存中根本就不存在
/////////////////////////////最后更新
只能得出赋了初值的对象占的空间大小?
我不知道你怎么测试的
object obj = new object();
long longtest = GetSpaceForObject(obj);
obj = "dsgjskdghsdkghsjkdghkdjkhgk43kjkfdkhjdkfjh";
longtest = GetSpaceForObject(obj);
obj += "aaafgfhdfhdfh"; ;
longtest = GetSpaceForObject(obj);

网路上好像获取对象内存占用空间方法不错,何况是.net的C#版本
不过书中好像有介绍:例如int占用4字节,long暂用8字节

char占用1字节,string根据实际情况来

你搜索下sizeof关键字

我不愿意对我目前没有需求而不了解的东西进行探讨!
////////////////////最新更新
觉得你这问题有点意思,刚才google下,所以我将方法打包送给你

using System;
using System.Xml;
using System.IO;
using System.Threading;
using System.Runtime.Serialization.Formatters.Binary;
class Test
{
static void Main()
{
long longtest = GetSpaceForObject("aaaaaaaaaaa");
}
static long GetSpaceForObject(object obj)
{
MemoryStream memory = new MemoryStream();
BinaryFormatter bin = new BinaryFormatter();
bin.Serialize(memory, obj);
memory.Position = 0;
return memory.Length;
}
}
第2个回答  2008-10-30
默认分配最大存贮空间
相似回答