MyObject obj = new MyObject();
我知道'new'关键字将调用构造函数并初始化托管堆中的对象。
我的问题是CLR如何执行以下操作。
最佳答案
创建引用类型(类,委托(delegate),接口(interface),字符串或对象)时,会将其分配到堆上。.Net具有四个不同的堆:(gen0,gen1,gen2)(小对象堆)和LOH(大对象)堆)。大小等于或小于85k的所有内容都会在前三个堆中的一个上进行,具体取决于创建时间(从gen0到gen1到gen2等)。大于85k的对象将放置在LOH上。 LOH永远不会被压缩,因此最终,我正在做的类型的分配最终将导致OOM错误,因为对象会分散在该内存空间中。这些被称为托管堆。
要创建一个对象,您需要做的就是使用new关键字。 .NET将负责在正确的堆上创建,初始化和放置对象,并保留任何必要的额外内存。之后,您几乎可以忘记该对象,因为完成该对象后不必删除它。
使用new关键字创建引用类型对象时,该对象将放置在堆上,并且其引用通常在当前运行的堆栈中使用。还有其他可能将您的对象用作引用的来源:
这5个实际上是GC的根节点,在这些根节点上形成了对象引用层次结构。想象一下经典的Customer类,该类通常具有一个存储Order类的集合。将订单添加到订单集合后,该集合本身将保留对已添加订单的引用。如果Customer类的实例也具有对其的堆栈引用。
这是复杂对象的层次结构的形成方式,这是GC如何查看引用的方式。
例如。
客户对象的堆栈引用->引用订单的列表对象->引用单个订单。
从这5个根源松散引用的任何内容都易于产生GC。
如何为对象分配内存有点复杂,并且通常会随着时间的增长以MKK的形式指定为http://msdn.microsoft.com/en-us/magazine/cc163791.aspx
一个简单的例子可能是:
class MyClass
{
string Test="Hello world Wazzup!";
byte[] data=new byte[86000];
}
很容易假设MyClass的大小在分配时包括:
•19个字符
•86,000字节。
实际上,对象的大小将仅包括通用类的内容,以及将对象指针存储到字符串和字节数组(类级别变量)所需的内存,然后将这些对象分别分配到堆中。该字符串将分配在SOH上,其对象引用由该类的实例保存;字节数组将分配给LOH,因为它大于85 KB。
SOH可以压缩,并且其中不会有碎片,而LOH可以在内存中具有碎片。
问候。
关于c# - 当我给MyObject obj = new MyObject()时会发生什么,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11027155/