这个问题是由
http://community.csdn.net/Expert/topic/5633/5633221.xml?temp=.3441278
这个帖子想到的。object o1 = new object();
实例化后的o1在托管堆中占用了多少个字节,每个字节里面代表的意义是什么?做程序测的结果是占用12字节,有趣的是,object本身有4个方法,12个字节是怎么存下4个方法的指针的,这还不算同步块索引和类型指针。ms是怎么实现它的呢?测试程序如下:
class Class1
{
static void Main(string[] args)
{
int b = 2;
object o1 = new object();
object o2 = new object();
unsafe
{
int* p = &b;
Console.WriteLine("&o1 = {0:X}", *(p - 1));
Console.WriteLine("&o2 = {0:X}, o1 size = {1}", *(p - 2), *(p - 2) - *(p - 1));
}
Console.ReadKey();
}
}
http://community.csdn.net/Expert/topic/5633/5633221.xml?temp=.3441278
这个帖子想到的。object o1 = new object();
实例化后的o1在托管堆中占用了多少个字节,每个字节里面代表的意义是什么?做程序测的结果是占用12字节,有趣的是,object本身有4个方法,12个字节是怎么存下4个方法的指针的,这还不算同步块索引和类型指针。ms是怎么实现它的呢?测试程序如下:
class Class1
{
static void Main(string[] args)
{
int b = 2;
object o1 = new object();
object o2 = new object();
unsafe
{
int* p = &b;
Console.WriteLine("&o1 = {0:X}", *(p - 1));
Console.WriteLine("&o2 = {0:X}, o1 size = {1}", *(p - 2), *(p - 2) - *(p - 1));
}
Console.ReadKey();
}
}
解决方案 »
- 【C#】简单form表单怎么在别的页面接收
- 怎么取得与变量相关的文本框的ID,也就是说怎么把一个变量赋给文本框的ID?
- 类成员或方法描述问题
- panel里加多个用户控件?
- ☆☆☆☆☆★C#中的UserControl问题——如何映射事件★☆☆☆★急问求解!☆☆☆☆☆☆☆☆☆☆☆☆☆☆
- 一个windows窗口我关闭后怎么让他再出来
- 求如何在窗体中显示pdf文件,要求打开的pdf文件不能保存到本地,不能打印,谢谢,在线等!!!
- 老问题再请教
- 关于TELNET选项协商的理解
- 请各位帮我看看这个程序里面哪个地方错了。
- 一个textbox,要求里面一定要输入内容,否则在后面显示一句提醒,怎么做?
- *****100分******请问winform怎样自动显示最新纪录
int b=1;
object o1 ..
object o2 .......
托管对象是引用类型
就算如lz所说
*(p - 2) - *(p - 1) =12 这里也只是3个指针的长度,而非object 的长度
object o1 = new object(); // 对象变量,实际上 o1 存储的只是一个指向 object 实例的引用
object o2 = new object();应该等价于// C++
object* o1 = new object(); // 指针变量, 存储空间开辟在 堆区
object* o2 = new object();而不是
// C++
object o1; // 对象变量,存储空间开辟在 栈区 (考虑局部变量,不考虑全局变量)
object o2; // 对象变量
所以......加上,hdt(倦怠) 的解释,应该可以从 宏观 上理解了至于,底层具体如何实现的,只有垂寻 Anders Hejlsberg,Don Box 他们了不管,怎么说,这确实是一个相当有意思的问题
指针大小都为4字节,无论什么指针,那么b的指针p,在栈上移动4字节(int型移动4)是(p-1),正好可以移动到o1在栈上的指针位置,这里主要是因为int的占用和指针占用大小一样,那么*(p-1)正好是指针o1指向托管堆的地址值,**(p-1)才是o1在托管堆的内容,如果看原贴的话会清楚很多,(p-1)是作为二重指针来用的。
public class Class2
{
private int a;
public int c;
public int d;
} class Class1
{
static void Main(string[] args)
{
int b = 2;
Class2 o1 = new Class2();
Class2 o2 = new Class2();
unsafe
{
int* p = &b;
Console.WriteLine("&o1 = {0:X}", *(p - 1));
Console.WriteLine("&o2 = {0:X}, o1 size = {1}", *(p - 2), *(p - 2) - *(p - 1));
}
Console.ReadKey();
}
}借用原作者的意思,直接这样输出结果20,去掉private int a;这句就变为16,再去掉 public int c;变12,最后把类清空了什么也没有,还是12。这说明内存地址还是连续的,不过在大点的程序中,连续的情况就难说了。
public class Class2
{
private int a;
public int c;
public int d;
} class Class1
{
static void Main(string[] args)
{
int b = 2;
Class2 o1 = new Class2();
Class2 o2 = new Class2();
unsafe
{
int* p = &b;
Console.WriteLine("&o1 = {0:X}", *(p - 1));
Console.WriteLine("&o2 = {0:X}, o1 size = {1}", *(p - 2), *(p - 2) - *(p - 1));
}
Console.ReadKey();
}
}借用原作者的意思,直接这样输出结果20,去掉private int a;这句就变为16,再去掉 public int c;变12,最后把类清空了什么也没有,还是12。这说明内存地址还是连续的,不过在大点的程序中,连续的情况就难说了。