这里我们讨论的两个东西:托管堆和垃圾回收器,前者是负责创建对象并控制这些对象的生存周期,后者负责回收这些对象。

一、托管堆分配资源

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

那么我们进一步深入看看创建一个对象(也就是new 一个对象)时CLR做了哪些工作呢。

1、计算类型字段需要的字节数。

2、加上对象开销所需要的字节数,每个对象都有两个开销:类型对象指针和同步块索引

3、CLR检查区域中可用空间够不够,如果够就在指针P指向的地址放入对象。

4、调用类型的构造器,new操作符返回对象引用。

5、返回对象引用之前指针P会移到下个对象放入托管堆时的地址。

二、垃圾回收器回收资源

应用程序调用new操作符创建对象时,可能没有足够的地址空间来分配该对象,发现空间不够,CLR就执行回收.

在讲GC时我们要明白几个概念:

  根:将所有引用类型的变量都称为根

可达和不可达:至少有一个根在引用对象时我们称这个对象可达,否则我们称之为不可达。

正式开始垃圾回收,我们参考上面的这个图,图中A,B、C、D、E就是我们托管堆上的对象,现在只有A和C两个对象被引用,E被C引用,步骤如下:

1、CLR开始GC时,前先暂停进程中的所有线程。

2、CLR遍历堆中的所有对象,将所有对象都标记为0,表示所有对象都应删除。

3、CLR检测所有活动根,任何根如果引用了堆上的对象CLR就会标记那个对象为1.注意这里的C引用了E,在标记C的时候还要判断E是否标识了1,如果标记了就不再标记,如果没有标记则标记为1

4、标记完后堆中的对象要么是已标记1,要么是未标记0,已标记的对象为可达的,未标记的对象为不可达的,GC会接下来会删除这些未标记的对象,也就是标记为0的对象

5、GC将对象删除后进入压缩阶段,将所有对象集中在一个连续的类存中,解决了本机的空间碎片化的问题,压缩完成后,CLR恢复应用程序的所有线程。

至此,一个对象的创建到回收就完成了。

C# 托管堆和垃圾回收器GC的更多相关文章

  1. 垃圾回收器(GC)

    值类型占用的空间在方法执行结束后会被马上释放, 引用类型占用的空间在方法结束后不会被马上释放,具体什么时间释放由垃圾回收器(GC)来决定. GC(Garbage Collection):JAVA/.N ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. nodejs+websocket实时聊天系统

    介绍下websocket: webSocket协议本质上是一个基于tcp的协议; 建立一个websocket连接,大体的过程: 1.客户端浏览器首先向服务器发起一个http请求,这个请求和平常的请求有 ...

  2. 【笔记】vue-cli 开发环境中跨域连接后台api(vue-resource 跨域post 请求)

    在vue-cli 项目中很多人会用到mock 数据(模拟数据),但是我觉得如果在真实的数据库交互中开发会更有安全感一些,所以查了一下百度很多人推荐的就是: 跨域! 跨域是什么概念?不同的主机名,同主机 ...

  3. Django将request对象传入模板配置

    对于很多时候,需要从模板中获取很请求中很多内容,比如当前请求的url,当前的session变量中的某个值,这时候我们可以通过配置可将request对象传递进模板. django1.10版本: sett ...

  4. scrapy_对传到items的值预处理

    如何实现对值进行预处理?  对于传递进items的值,首先明白有两个动作,进和出,那就可以分别对这两个动作进行逻辑处理 #!/usr/bin/python3 # -*- coding: utf-8 - ...

  5. string用法总结

    要想使用标准C++中的string类,必须要包含#include <string> 注意是<string>而不是<string.h>,带.h的是C语言中的头文件 s ...

  6. Python初识 - day5

    一.装饰器(decorator) 1.定义:本质是函数(装饰其它函数),就是为了其它函数添加附加功能. 2.原则:一是不能修改被装饰函数的源代码:二是不能修改被装饰函数的调用方式. 3.装饰器包含的知 ...

  7. Python 斐波那契数列练习

    # coding=gbk # 迭代法---1 def fibonacci (n): if n == 0 or n == 1: return n else : a = 0 b = 1 for i in ...

  8. Arrays.sort解析

    Arrays.sort()解读 在学习了排序算法之后, 再来看看 Java 源码中的, Arrays.sort() 方法对于排序的实现. 都是对基本数据类型的排序实现, 下面来看看这段代码: Arra ...

  9. 号外号外!解决github+hexo+yilia评论插件的问题!!!

    先走一波效果图!    本人网站--http://www.wenzheng.club/ ps:效果还是不错的,支持QQ微信登录,支持表情,甚至gif动图评论! 插件采用韩国服务器的来必力评论插件--h ...

  10. Jetson TX2安装固态硬盘(原创)

    SSD on Jetson TX2 注意事项:在断电情况下,将固态硬盘的接线与Jetson TX2进行连接 步骤: 一.jetson tx2开机,打开搜索栏中的Disks 二.Disks显示画面 三. ...