CLR via C#(二)线程栈与托管堆

文章详细阐述了.NETCLR中对象的创建过程,包括System.Object的基本方法,new操作符如何分配内存和调用构造器,以及线程栈的工作机制,如参数传递和局部变量存储。同时,讨论了托管堆的管理,特别是对象生命周期和垃圾回收。此外,还涉及到了类型对象指针、同步块索引的概念以及虚方法和非虚方法的调用机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、System.Object

运行时要求每个类型最终都要从System.Object派生,它提供了如下几个基本方法:

方法名 说明
Equals() 虚方法。两个对象具有相同的值,就返回true
GetHashCode() 虚方法。返回对象的哈希码
ToString() 虚方法。默认返回类型的完整名称
GetType() 非虚方法。指出对象是什么类型
MemberwiseClone() 非虚方法。创建该类型的新实例,且其实例字段与this的实例字段完全一致
Finalize() 虚方法。在对象内存被回收之前会被调用

CLR要求所有的对象都用new操作符创建。比如:
Apple apple = new Apple();

在这期间,new操作符其实做了以下几件事情:

  • 计算类型及其所有基类型中定义的所有实例字段所需的字节数。此外,还需要加上一些额外的成员所占的字节数,包括:类型对象指针同步块索引,还有一个未公开的内部字段(用于计算对象实例的哈希值)。
  • 从托管堆中分配计算好的字节数的内存,并且所有的二进制位都初始化为0。
  • 初始化对象的“类型对象指针”和“同步块索引”。
  • 调用类型的构造器,传递指定的实参。每个类型的构造器都负责初始化自己的实例字段。最终会调用到System.Object的构造器,并返回。

new执行完这些操作后,会返回指向新建对象的一个引用。

上面有几个名词需要解释一下:
实例字段:指非静态字段,是属于对象的。与之相对的静态字段是属于类的。
类型对象指针:每个对象都是一个类型的实例,而每个类型都由一个Type类型的实例来表示。类型对象指针就是指向该Type实例的指针。当然,Type类型对象本身也是一个类型对象的实例,它的类型对象指针指向了它自己。
同步块索引:可以简单理解为一个指向“同步块”的指针,拥有这个同步块的对象可以支持线程同步。

二、线程栈

线程创建时会分配1MB的栈。栈空间用来向方法传递实参,方法内部定义的局部变量也存在栈上。栈从高位内存地址向低位内存地址构建

假如线程要调用下面的M1方法:

void M1()
{
   
	string name = "Joe";
	M2(name);
	// ...
	return;
}
void M2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值