1. 访问一个资源所需的步骤

  1). 调用IL指令newobj,为代表资源的类型分配内存(一般使用C# new 操作符来完成)。

  2). 初始化内存,设置资源的初始状态并使资源可用。类型的实例构造器负责设置初始状态。

  3). 访问类型的成员来使用资源(有必要可以重复)。

  4). 摧毁资源的状态以进行清理。

  5). 释放内存。垃圾回收器独自负责这一步。

分配并初始化资源并直接使用。大多数类型都无需资源清理,垃圾回收器会自动释放内存。

2. 从托管堆分配资源

 CLR 要求所有对象都从托管堆分配。进程初始化时,CLR划出一个地址空间区域作为托管堆。CLR还要维护一个指针,我把它称作NextObjPtr。该指针指向下一个对象在堆中的分配位置。

 一个区域被非垃圾对象填满后,CLR会分配更多区域。这个过程一直重复,直到整个进程地址空间被填满。所以,你的应用程序的内存受进程的虚拟地址空间的限制。32位进程最多能分配1.5GB,64位进程最多能分配8T。

3. new操作符导致CLR执行以下步骤

  1). 计算类型的字段(以及从基类型继承的字段)所需的字节数

  2). 加上对象的开销所需的字节数。每个对象都有两个开销字段:类型对象指针和同步块索引。对于32位应用程序,这两个字段各自需要32位,所以每个对象要增加8个字节。对于64位应用程序,这两个字段各自需要64位,所以每个对象要增加16个字节。

  3). CLR检查区域中是否有分配对象所需的字节数。如果托管堆有足够的可用空间,就在NextObjPtr指针指向的地址处放入对象,为对象分配的字节会被清理。接着调用类型的构造器(为this参数传递NextObjPrt),new操作符返回对象引用。就在返回这个引用之前,NextObjPrt指针的值会加上对象占用的字节数得到一个新值,即下个对象放入托管堆时的地址。

4. 垃圾回收算法。应用程序调用new操作符创建对象时,如果第0代没有只够的地址空间来分配对象,CLR就执行垃圾回收。

引用追踪法:CLR开始GC时,首先暂停进程中的所有线程。这样可以防止线程在CLR检查期间访问对象并更改其状态。然后,CLR进入GC的标记阶段。在这个阶段,CLR便利堆中的所有对象,将同步块索引字段中的一位设为0,这表明所有对象都应删除。然后,CLR检查所有活动的根,查看它们引用了哪些对象。如果根引用了堆上对象,则将同步块索引字段中的一位设为1。检查完毕后,未标记的会被删除,已标记的会被转移,并从每个根减去所引用的对象的内存中偏移的字节数。

静态字段应用一直存在,直到用于加载类型的AppDomain卸载为止(考虑内存泄漏)。

5. GC是基于代的垃圾回收器。共有第0代,第1代和第2代。第0代对象就是那些新构造的对象。CLR初始化时为第0代对象选择一个预算容量(以KB为单位)。如果分配一个新对象造成第0代超过预算,就启用一次垃圾回收,垃圾回收中存活的对象现在成为第1代,第0代不再包含任何对象。第2代同理。预算是根据回收量动态调节的

6. 触发GC的条件

  1). 第0代超预算时

  2). 显示调用GC.Collect方法

  3). window报告低内存情况,通过 CreateMemoryResourceNotification 和 QueryMemoryResourceNotification监视系统总体内存使用情况

  4). AppDomain卸载时

7. 大对象。超过85000字节或更大的对象。

  1). 大对象不是在小对象的地址空间分配,而是在进程地址空间的其他地方分配的。

  2). 目前版本GC不压缩大对象,可能会造成碎片化。

  3). 大对象总是2代。不可能是 1代或0代。只能为长时间存活的资源创建大对象。

8. GC模式

  1). 工作站:默认值;该模式针对客户端应用程序优化GC。GC造成的延时成本很低,应用程序线程挂起时间很短,避免使用户感到焦虑。

  2). 服务器:该模式针对服务器端应用程序优化GC。被优化的主要是吞吐量和资源利用。GC假定机器上没有运行其他应用程序,并假定机器的所有CPU都可用来辅助完成GC。该模式造成托管堆被拆分成几个区域,每个CPU一个。开始垃圾回收时,垃圾回收器在每个CPU上都运行一个特殊线程;每个线程都和其他线程并发回收它自己的区域。对于工作者线程(worker thread)行为一致的服务器应用程序,并发回收能很好的进行。

9. Finaliize 方法。被视为垃圾的对象在垃圾回收完毕后才调用Finalize方法,所以这些对象的内存不是马上被回收,因为Finalize方法可能要执行访问字段的代码。可终结对象在回收时必须存活,造成它被提升到另一代,使对象活的时间比正常的长。

CLR via C# 笔记 -- 托管堆和垃圾回收(21)的更多相关文章

  1. C#托管堆和垃圾回收

    垃圾回收 值类型 每次使用都有对应新的线程栈 用完自动释放 引用类型 全局公用一个堆 因此需要垃圾回收 操作系统 内存是链式分配 CLR 内存连续分配(数组) 要求所有对象从 托管堆分配 GC 触发条 ...

  2. CLR via C# 读书笔记-21.托管堆和垃圾回收

    前言 近段时间工作需要用到了这块知识,遂加急补了一下基础,CLR中这一章节反复看了好多遍,得知一二,便记录下来,给自己做一个学习记录,也希望不对地方能够得到补充指点. 1,.托管代码和非托管代码的区别 ...

  3. 【CLR】解析CLR的托管堆和垃圾回收

    目录结构: contents structure [+] 为什么使用托管堆 从托管堆中分配资源 托管堆中的垃圾回收 垃圾回收算法 代 垃圾回收模式 垃圾回收触发条件 强制垃圾回收 监视内存 对包装了本 ...

  4. 重温CLR(十五) 托管堆和垃圾回收

    本章要讨论托管应用程序如何构造新对象,托管堆如何控制这些对象的生存期,以及如何回收这些对象的内存.简单地说,本章要解释clr中的垃圾回收期是如何工作的,还要解释相关的性能问题.另外,本章讨论了如何设计 ...

  5. 【C#进阶系列】21 托管堆和垃圾回收

    托管堆基础 一般创建一个对象就是通过调用IL指令newobj分配内存,然后初始化内存,也就是实例构造器时做这个事. 然后在使用完对象后,摧毁资源的状态以进行清理,然后由垃圾回收器来释放内存. 托管堆除 ...

  6. .NET 托管堆和垃圾回收

       托管堆基础 简述:每个程序都要使用这样或那样的资源,包括文件.内存缓冲区.屏幕空间.网络连接.....事实上,在面向对象的环境中,每个类型都代表可供程序使用的一种资源.要使用这些资源,必须为代表 ...

  7. 托管堆和垃圾回收(GC)

    一.基础 首先,为了深入了解垃圾回收(GC),我们要了解一些基础知识: CLR:Common Language Runtime,即公共语言运行时,是一个可由多种面向CLR的编程语言使用的"运 ...

  8. cir from c# 托管堆和垃圾回收

    1,托管堆基础 调用IL的newobj 为资源分配内存 初始化内存,设置其初始状态并使资源可用.类型的实列构造器负责设置初始化状态 访问类型的成员来使用资源 摧毁状态进行清理 释放内存//垃圾回收期负 ...

  9. 如何管好.net的内存(托管堆和垃圾回收)

    一:C#标准Dispose模式的实现 需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CL ...

  10. C# 托管堆和垃圾回收器GC

    这里我们讨论的两个东西:托管堆和垃圾回收器,前者是负责创建对象并控制这些对象的生存周期,后者负责回收这些对象. 一.托管堆分配资源 CLR要求所有的对象都从托管堆分配.进程初始化时,CLR划出一个地址 ...

随机推荐

  1. 2019-9-30-dotnet-枚举当前设备wifi热点

    title author date CreateTime categories dotnet 枚举当前设备wifi热点 lindexi 2019-09-30 14:42:18 +0800 2019-9 ...

  2. JavaScript之变量解构赋值的使用

    引言 解构赋值是ES6中引入的一种能快速方便的进行变量赋值的方法,其主要也就是分为解构和赋值两部分内容.解构者,也就是匹配结构,然后分解结构进行赋值. 数组的解构赋值 使用 const arr = [ ...

  3. Redisant Toolbox——面向开发者的多合一工具箱

    Redisant Toolbox--面向开发者的多合一工具箱 Redisant Toolbox 拥有超过30种常用的开发工具:精心设计,快速.高效:离线使用,尊重您的隐私.官网地址:http://ww ...

  4. Mybatis学习四(分页助手pagehelper)

    Mybatis学习过程中有一个很重要的插件分页助手(pagehelper) 能够运用这个插件也非常简单 1.导入jar包 [jsqlparser-2.0.jar包] [点击下载https://gith ...

  5. Solution Set - 点分治

    A[POJ1741].给定一棵树,边有权,求长度不超过\(k\)的路径数目. B[HDU4871].给定一张图,边有权,求它的最短路径树上恰含\(k\)个点的路径中最长路径的长度及数目. C[HDU4 ...

  6. 简说Python之面向对象

    目录 Python对象 对象的内置方法 __init__方法 __str__方法 对象的多态 对象的封装 对象的继承 之前介绍了函数.对象代表了什么.可以称为"一篮子"计划,把数据 ...

  7. lodash中的深拷贝方法cloneDeep()

  8. 解决Host key verification failed.(亲测有效)

    哈喽哇,今天在访问远程服务器的时候,出现了一个小问题. 原因:之前ssh联系过服务器,重置服务器后,再次连接服务器,就会出这个问题. 一.发现问题 问题如下图代码: $ ssh root@108.61 ...

  9. HDU 多校 2023 Round #5 题解

    HDU 多校 2023 Round #5 题解 \(\text{By DaiRuiChen007}\) A. Typhoon Problem Link 题目大意 给一条 \(n\) 个点构成的折线,\ ...

  10. Nifi:Nifi中的Controller Service

    Service简介 首先Nifi中的Controller Service 和我们MVC概念中的Controller Service不是一个概念,Nifi中的Controller Service更像是和 ...