c# object占多少字节
发布时间:2025-05-19 17:31:21 发布人:远客网络
一、c# object占多少字节
1、Object占多少内存,谁也不知道,按照非托管的想法是,如果你只定义一个类,而它没有任何数据成员,我在VS2008下,使用默认字节对齐,
2、这样得出来 sizeof( Object)为 1。
3、在C#里,是不能直接获取object占用内存大小的,因为它根本不是一个标准的布局。
4、而楼上的BinaryFormatter的方法,只是以二进制格式将对象或整个连接对象图形序列化和反序列化。它甚至还有可能包含版本信息,所以它的结果并不能代表一个对象所占用内存的大小。
5、C#提供了一种可以获取一个对象的非托管内存的大小的方法。但是必须在显式指定了内存布局以及字节对齐等信息的对象上才可以使用。
6、[StructLayout( LayoutKind.Sequential)]
7、,大家都知道,所有的对象都是从MyObject继承而来的,也就是说,我们上面这个MyObject类,也隐含的继承了Object。
8、int size= Marshal.SizeOf( typeof( MyObject));
9、看来跟C++是一样的。也就是说,一个未定义任何数据成员的空对象,其占用1字节的内存。
10、那么我们再来看看一些标准成员的大小,比如int,long,double等。
11、int size= Marshal.SizeOf( typeof( int));//结果为4
12、int size= Marshal.SizeOf( typeof( long));//结果为8
13、int size= Marshal.SizeOf( typeof( float));//结果为4
14、int size= Marshal.SizeOf( typeof( double));//结果为8
15、可见,这些基本数据类型,与非托管下的大小是没有区别的。
16、那么现在我们来看看混合在一起的情况。
17、[StructLayout( LayoutKind.Sequential)]
18、然后我们执行 int size= Marshal.SizeOf( typeof( MyDataObject));
19、为什么是24呢,是因为我们指定了LayoutKind.Sequential,它的MSDN的说明如下:
20、对象的成员按照它们在被导出到非托管内存时出现的顺序依次布局。这些成员根据在 System.Runtime.InteropServices.StructLayoutAttribute.Pack中指定的封装进行布局,并且可以是不连续的。
21、那么,MyOjbect的大小实际上就是所有数据成员内存字节对齐后然后结构体的大小。
22、则VS2008上,字节对齐(即StructLayoutAttribute.Pack)默认设置好像是8。
23、下面是MyDataObject对象在默认设置下的对齐情况:
24、成员偏移位置(字节)内存分布(字节)
25、现在我们来看字节对齐为4的情况:
26、成员偏移位置(字节)内存分布(字节)
27、成员偏移位置(字节)内存分布(字节)
28、字节对齐为1的情况:这就是最紧凑的情况了。
29、成员偏移位置(字节)内存分布(字节)
30、总体上来说,.net的对象占用的空间,跟其它非托管程序是一样的,只是大部分的对象,由于是托管的,而且没有规定内存布局,所以我们无法获得其真正占用内存的大小。
31、StructLayoutAttribute类和Marshal类位于命名空间“System.Runtime.InteropServices”下。
32、本来上面的对齐的排列顺序,我写的的时候中间有好几个空格的,不知道为什么发上来就成一个空格了,排版不好看了,效应着看吧,呵呵
33、//------------我也来更新一下,不知道你们两个人在争什么?
34、.net是中间语言,什么叫做托管?托管的主要意思就是它把内存控制权接管了,简之,你所写的代码并不是像C/C++那样对内存的精确控制。
35、就拿C#来说,它是号称没有指针,但是,实际上大家都看得出来,它的所谓引用型参数,就是指针。为什么这么说?你试试调用一个非托管的API,如果那个参数是指针类型的话,那你就得用ref了。
36、就拿你的问题ClassA a来说,现在我们就假定.net内部是指针,那么
37、ClassA a,就相当于是定义了一个指针,我们知道,指针在32位系统下,占4字节。当然,这里还有一个前提,就是ClassA是一个class,不是struct或者其它值类型。
38、至于string类型的成员的占用内存的大小,不知道楼主你会不会C++,有没有见过std的string是怎么实现的?为了提交效率,降低内存分配频率,string对象在创建时,就会默认了一个容量长度,这个跟它存储的字符串长度是不一样的,如果存储的字符串长度超过了容量,那么它会再重新分配一块更大的内存来存储。但目前我还没看到.net的String对象的源代码,所以不知道它的默认容量是多大,那个就应该是它默认占的内存大小。我只知道StringBuilder的默认容量是16,我想string的也许更大些吧。
39、末了,不知道你们讨论一个托管对象的占用内存大小还有什么意义。
40、我想你以为我这么在一段,是哪里COPY来吧,不好意思,我没有COPY别人答案的习惯,全是手敲的,有空的就把我的话,当废话看吧,我也没什么成见,就发表个人观点而已。
二、js 获取字符串出现的位置
要实现判断字符存在字符串在的位置,在js中利用indexof来实现;
stringobject.indexof(searchvalue,fromindex)
<script type="text/网页特效">
document.write(str.indexof("h")+"<br/>")//0
document.write(str.indexof("world")+"<br/>")//-1
document.write(str.indexof("world"))//6
该方法将从头到尾地检索字符串 stringobject,看它是否含有子串 searchvalue。开始检索的位置在字符串的 fromindex处或字符串的开头(没有指定 fromindex时)。
如果找到一个 searchvalue,则返回 searchvalue的第一次出现的位置。stringobject中的字符位置是从 0开始的。
下面的示例说明了 indexof方法的用法。
var str1="babebibobubabebibobu"
注释:indexof()方法对大小写敏感!
注释:如果要检索的字符串值没有出现,则该方法返回-1。
三、js中var a=new Object()和var a={}有什么区别吗
应该是没有区别的,两者都是生成一个默认的Object对象。js和其它语言一样,一切对象的基类都是Object,所以,new Object()和简易的{}是同样的空对象,就是默认的对象。本来我以为{}应该是一个没有任何属性和方法的对象,但事实证明,var a={},a.toString()等Object对象所具有的方法,a都具有。由此也可以判断,其实a={}就是a= new Objcet()的简单实现。就像在java语言中,String str=""和String str= new String()都是创建String的对象一样。