Net-GC垃圾回收
2021-03-26 01:24
标签:col 过程 next http 垃圾回收 静态 cpu 新生代 文件 CLR要求所有的对象都是从托管堆分配。 CLR划出一个地址空间区域作为托管堆。 CLR还要维护一个指针,NextObjPtr。 用来指向下一个对象在堆中分配的位置。 一个区域被非垃圾对象填满,CLR会分配更多的区域。一直重复,直到整个进程的地址空间被填满。所以你的应用程序受进程的虚拟地址空间限制。 32位-1.5GB 64位-8TB。 1.计算类型的字段(包括基类继承的字段成员)所需的字节数 2. ***加上对象的开销所需的字节数***。 a类型对象指针(属于哪个类) b同步块索引 (线程同步所需,垃圾回收使用) (32位程序,这两个字段各许32位,一共8个字节) (64位程序,这两个字段各需64位,一共16个字节) 3.CLR检查区域是否够大,如果够大就在NextObjPtr指针指向的地址放入对象。 同时将指针向后移动。 此处有个优化点:CPU从内存中读取数据,是成页读取的,连续分配则能减少CPU读取内存的次数。 如果一直分配的话,可能很快将内存占用满,所以需要GC来回收内存。--垃圾回收 当new对象的时候,发现没有足够的地址空间来分配对象,则CLR就执行垃圾回收。 事实上是在第0代满的时候就会执行GC。 根:我们将所有引用类型的变量都称之为 根。 在CLR执行GC的时候,会暂停进程中的所有线程。防止线程在CLR检查期间访问对象并改变其状态。然后CLR进入标记阶段。 CLR遍历所有对象,将同步块索引中的一位设为0。表示所有对象都应删除。 然后检查所有的活动根,查看他们引用了哪些对象,任何根如果引用了堆上的对象,CLR就会标记这个对象,将同步块索引中的位设为1。 一个对象被标记后,CLR会检查对象中的根,标记他们引用的对象。如果发现对象已经被标记,就不重复检查对象的字段,避免循环引用。 一次垃圾回收过程,标记为0的对象就应该被收回。 OutOfMemeryException异常:当内存耗尽,还要进行new或者进行对象分配时,会抛出该异常。---比如死循环。 一个常见的原因就是:静态字段引用了集合对象,然后不停的向集合添加数据项。静态字段中对象一直存活,垃圾回收不掉,导致内存泄漏。因此,应尽量避免使用静态字段。 垃圾回收中的代:0代,1代,2代。GC.MaxGeneration 0代为新生代,2代为最老的代。 新创建的对象都是0代。 CLR会在内存中分配固定大小的代。0代多大,1代多大,2代多大。 过程: 如果0代内存已满,进行GC,标记阶段,不可达的或者说没有引用的标记为0.并从内存中移除 将正在使用的对象标记为1,并转移到1代区域, 同理,CLR会对第1代进行内存分配,当第0代满时,进行GC,0代移动到1代,1代满时,对1代区域进行回收,发现没有可回收对象时,将1代转移到2代,0代转移到1代,0代空出来。 如果第0代全是垃圾的时候,只需要将NextObjPtr指针指向内存头部即可,不必进行垃圾回收。 优化:其实如果垃圾回收了第0代,发现还有许多对象存活,没有多少内存被回收,就会增大0代预算。0,1,2代预算都可以被优化,增大或者缩小预算。 出发垃圾回收的条件: l 代码显示调用GC.Collect()方法 l Windows报告内存过低 l CLR正在卸载AppDomain l CLR正在关闭 以上都是小对象 85000字节或者更大的对象。 GC不压缩大对象,因为移动大对象代价过高。 大对象总是在2代,不可能放到0或1代。 大对象一半是大字符串 XML或JSON或者用于IO操作的字节数组(比如从文件或者网络将字节读入缓冲区以便处理) Net-GC垃圾回收 标签:col 过程 next http 垃圾回收 静态 cpu 新生代 文件 原文地址:https://www.cnblogs.com/alua/p/12643770.html1对象的分配
1.1对象的分配过程
2垃圾回收算法
2.1垃圾回收的算法
标记阶段:
内存泄漏
2.2代:提升性能
2.3垃圾回收触发条件
2.4大对象
上一篇:PHP trim()函数详解
下一篇:网站变灰效果实现