Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当我给MyObject obj=newmyobject()时发生了什么_C#_.net_Garbage Collection_Clr - Fatal编程技术网

C# 当我给MyObject obj=newmyobject()时发生了什么

C# 当我给MyObject obj=newmyobject()时发生了什么,c#,.net,garbage-collection,clr,C#,.net,Garbage Collection,Clr,我知道'new'关键字将调用构造函数并初始化托管堆中的对象 我的问题是CLR如何做以下工作 CLR如何执行上述行 CLR如何为对象分配Memory CLR如何确定对象的大小 如果堆中没有空间为对象分配内存,CLR如何知道这一点 创建引用类型(类、委托、接口、字符串或对象)时,会将其分配到堆中。.Net有四个不同的堆:(gen0、gen1、gen2)(小对象堆)和LOH(大对象堆)。85k或更小的所有数据都会根据创建时间(从gen0到gen1再到gen2,等等)在前三个堆中的一个堆中存储。大于85

我知道'new'关键字将调用构造函数并初始化托管堆中的对象

我的问题是CLR如何做以下工作

  • CLR如何执行上述行
  • CLR如何为对象分配Memory
  • CLR如何确定对象的大小
  • 如果堆中没有空间为对象分配内存,CLR如何知道这一点

  • 创建引用类型(类、委托、接口、字符串或对象)时,会将其分配到堆中。.Net有四个不同的堆:(gen0、gen1、gen2)(小对象堆)和LOH(大对象堆)。85k或更小的所有数据都会根据创建时间(从gen0到gen1再到gen2,等等)在前三个堆中的一个堆中存储。大于85k的对象将放置在LOH上。LOH永远不会被压缩,所以最终,我正在执行的类型的分配将最终导致OOM错误,因为对象将分散在该内存空间中。这些称为托管堆

    要创建对象,只需使用new关键字。NET将负责创建、初始化对象并将其放置在正确的堆上,并保留任何必要的额外内存。在那之后,你几乎可以忘记那个对象,因为你不必在处理完它后删除它

    当您使用new关键字创建引用类型对象时,它被放置在堆上,并且它的引用主要在当前运行的堆栈中使用。还有其他可能的源可以将对象用作参考:

  • 全局/静态对象引用
  • CPU寄存器
  • 对象终结引用(稍后详细介绍)
  • 互操作引用(.NET对象传递给COM/API调用)
  • 堆栈引用(此处主要使用)
  • 这5个节点实际上是GC根节点,对象引用层次结构就是从这里形成的。将订单添加到订单集合时,集合本身将保存对添加订单的引用。如果Customer类的实例也有对它的堆栈引用

    这是复杂对象的层次结构形成方式,这是GC查看引用的方式

    e:g。 客户对象堆栈引用->订单列表对象引用->单个订单引用

    从这5个根中松散引用的任何内容都容易发生GC

    内存分配给对象的方式有点复杂,通常会随着时间的推移而增长,如指定的MKK

    一个简单的例子是:

    MyObject obj = new MyObject();
    
    很容易假设MyClass在分配时的大小包括:

    •19个字符

    •86000字节

    事实上,对象的大小将只包括一般类内容,以及存储指向字符串和字节数组(类级变量)的对象指针所需的内存,然后将这些指针分别分配到堆上。字符串将分配给SOH,其对象引用由类的实例持有;字节数组将被分配到LOH上,因为它大于85 KB

    SOH可以被压缩,其中不会有碎片,而LOH可以在内存中有碎片


    问候。

    我建议您通过C#阅读
    CLR--Jeffrey Richter,以获得更好的洞察力
    
    class MyClass 
    { 
        string Test="Hello world Wazzup!"; 
        byte[] data=new byte[86000];  
    }