MyObject obj = new MyObject();
我知道'new'关键字将调用构造函数并初始化托管堆中的对象。
我的问题是CLR如何做到以下。
答案 0 :(得分:2)
当创建引用类型(类,委托,接口,字符串或对象)时,它被分配到堆上.Net有四个不同的堆:(gen0,gen1,gen2)(小对象堆) )和LOH(大对象堆)。根据创建时间(从gen0移动到gen1到gen2等),前五个堆之一的85k或更小的所有内容都会出现。大于85k的物体放置在LOH上。 LOH永远不会被压缩,因此最终,I类型的分配最终将导致OOM错误,因为对象散布在该内存空间周围。这些被称为托管堆。
要创建对象,您只需使用new关键字; .NET将负责创建,初始化和将对象放在正确的堆上,并保留必要的额外内存。在那之后你几乎可以忘记那个对象,因为当你完成它时你不必删除它。
使用new关键字创建引用类型对象时,它将放在堆上,其引用主要用于当前运行的堆栈。还有其他可能的来源,您的对象可以用作参考:
这5个实际上是形成对象引用层次结构的GC根节点。想象一下经典的Customer类,它通常有一个存储Order类的集合。将订单添加到订单集合后,集合本身将保留对添加订单的引用。如果Customer类的实例也有一个堆栈引用。
这是如何为复杂对象形成层次结构,这就是GC查看引用的方式。
E:克。 Customer对象的stack-reference - >对订单的List对象的引用 - >参考个别订单。
任何从这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可能会在内存中碎片化。
问候。