[.NET] GC垃圾回收机制
前言:
在.NET程序开发中,为了将开发人员从繁琐的内存管理中解脱出来,将更多的精力花费在业务逻辑上,CLR提供了自动执行垃圾回收的机制来进行内存管理。开发人员甚至感觉不到这一过程的存在。CLR执行垃圾回收的过程,有以下几点:
- 如何判断哪些对象是可以进行回收的,哪些是要保留的?
- 对象在堆上是如何分布的?何时执行垃圾回收?
- 垃圾回收的过程如何进行的?有哪些优化策略?
判断哪些对象需要进行回收
垃圾回收,第一步要判断哪些对象需要被GC回收掉。简而言之,那些在代码的任何位置也无法访问到的对象是需要被GC回收掉的。
GC借助于应用程序根(Application Roots)和对象图(Object Graph)来判断哪些对象需要被回收。应用程序根保存了堆上对象的引用,如果一个对象没有直接或者间接的被应用程序根所引用,那么就说明没有任何代码可以访问到它,因此这个对象可以被回收。
应用程序根只是一个入口点,一个对象可能持有其他一个或者多个对象的引用,这种对象间的引用关系构成了对象图。每次创建新对象,在复制引用、删除引用,或者执行垃圾回收之后,CLR都会自动更新它。
对象如何分配在堆上
.NET中的对象创建在托管堆上,托管堆维护着一个指针,这个指针标识了下一个将要创建的新对象所在位置,通常称作新对象指针。该指针总是位于托管堆的末尾。当使用new运算符创建对象时,CLR将会执行下面几个主要操作:
- 计算此对象所要分配的内存大小;
- 检查托管堆,确保托管堆有足够的空间来建立这个对象。如果空间够,将会调用构造函数来创建对象,并在托管堆末尾创建对象,然后返回对象在托管堆上的引用。引用的地址即为新对象指针所指向的地址。如果空间不够,则会执行一次垃圾回收来释放空间;
- 修改新对象指针的值,使它指向上一个可用的地址。
垃圾回收的执行过程
GC有许多算法,常见的算法有Reference Counting, Mark Sweep, Copy Collection等,目前主流的虚拟系统.NET CLR, Java VM都采用的Mark Sweep算法。Mark-Sweep标记清除阶段:先假设Managed Heap中所有对象都可以被回收,然后找出不能回收的对象,给这些对象打上标记,最后Managed Heap中没有打标记的对象都可以被回收。Compact压缩阶段:对象回收之后Managed Heap内存空间变得不连续,在Managed Heap中移动这些对象,使他们重新从Managed Heap基地址开始连续排列。
执行垃圾回收的时机:
- 当通过new关键字创建对象时,如果发现托管堆所占用的内存已经达到一个临界点,就会进行垃圾回收;
- 应用程序退出时也会执行一次垃圾回收;
- 调用System.GC.Collection()方法强制执行;
垃圾回收过程中的优化策略
垃圾回收过程中还采用了一些优化策略,主要时对象代(Object Generation)和大对象堆(Large Object Heap)
1. 对象代
对象共分了三个代级:
- 第0代:新近分配在托管堆上的对象,从来没有被GC回收过,任何一个新对象,当它第一次被分配在托管堆上时,就是第0代;
- 第1代:经历过一次垃圾回收后,依然保留在堆上的对象;
- 第2代:经历过两次或者以上垃圾回收后,依然保留在堆上的对象。
当进行垃圾回收时,垃圾回收器将会首先检查所有的第0代对象,并对其中可回收的对象进行清理。如果清理后获得足够的空间,经历过垃圾回收后的对象将提升为第1代对象。
如果所有的第0代对象都检查过了,但是内存空间还不够,那么将会检查第1代对象的可访问性,并进行垃圾回收。此时,如果经历过垃圾回收的第1代对象仍保留在堆上,则会升级为第2代对象。类似的,如果内存仍不够用,将会对第2代对象进行检查和垃圾回收。如果第2代的部分对象在此次垃圾回收后仍然保留在堆栈上,它依然是第2代对象。因为总共定义了3代对象。如果第2代对象在进行完垃圾回收后空间依然不够用,则会抛出OutOfMemoryException异常。
可见,最容易清理掉的就是那些新对象。
2. 大对象堆
垃圾回收的过程中有一个很影响性能的地方,就是在压缩的过程中,因为要批量地挪动对象,以填充腾出来的空间,如果对象很大,那么要移动的数据量就会很大。
如果将大对象直接分配在第0代,那么第0代的空间很快就会被占满,从而迫使CLR执行一次垃圾回收,这样执行垃圾回收的次数就会变得很频繁。
因此,第二个优化策略就是采用大对象堆,当对象大小超过85kb时,就会被分配在大对象堆上。大对象堆有几个特点:
- 没有代级的概念,所有对象都被视为第2代对象;
- 不进行对象移动和空间压缩,因为移动大对象是相对耗时的操作。
- 对象不会被分配在末尾,而会在链表中找合适的位置,因此会存在碎片问题。
至此,就对.NET GC有了一个基本的了解。感谢您的阅读~
[.NET] GC垃圾回收机制的更多相关文章
- JVM和GC垃圾回收机制和内存分配
JVM运行期间 线程共享 线程私有 线程共享: 方法区 堆方法区:存放可以共享数据,静态常量,类的共有方法属性字段等,可以共享的存在方法区. 堆:存放class对象 . 线程私有:本地方法栈 虚拟机栈 ...
- JVM架构和GC垃圾回收机制
深入理解系列之JDK8下JVM虚拟机(1)——JVM内存组成 https://blog.csdn.net/u011552404/article/details/80306316 JVM架构和GC垃圾回 ...
- java面试题之----JVM架构和GC垃圾回收机制详解
JVM架构和GC垃圾回收机制详解 jvm,jre,jdk三者之间的关系 JRE (Java Run Environment):JRE包含了java底层的类库,该类库是由c/c++编写实现的 JDK ( ...
- 面试官,不要再问我“Java GC垃圾回收机制”了
Java GC垃圾回收几乎是面试必问的JVM问题之一,本篇文章带领大家了解Java GC的底层原理,图文并茂,突破学习及面试瓶颈. 楔子-JVM内存结构补充 在上篇<JVM之内存结构详解> ...
- 乐字节Java|GC垃圾回收机制、package和import
本文接上一篇:乐字节Java|this关键字.static关键字.block块.本文是接着讲述JavaGC垃圾回收机制.package 和 import语句. 一.GC垃圾回收机制 GC全名:Garb ...
- 通俗易懂.NET GC垃圾回收机制(适用于小白面试,大牛勿喷)
情景:你接到xx公司面试邀请,你怀着激动忐忑的心坐在对方公司会议室,想着等会的技术面试.技术总监此时走来,与你简单交谈后.... 技术:你对GC垃圾回收机制了解的怎么样? 你:还行,有简单了解过. 技 ...
- GC垃圾回收机制详解
JVM堆相关知识 为什么先说JVM堆? JVM的堆是Java对象的活动空间,程序中的类的对象从中分配空间,其存储着正在运行着的应用程序用到的所有对象.这些对象的建立方式就是那些new一类的操作 ...
- C# GC 垃圾回收机制
今天来谈谈C# 的GC ,也就是垃圾回收机制,非常的受教,总结如下 首先:谈谈托管,什么叫托管,我的理解就是托付C# 运行环境帮我们去管理,在这个运行环境中可以帮助我们开辟内存和释放内存,开辟内存一般 ...
- asp.net 之 GC (垃圾回收机制)
今天抽时间好好整理了下GC相关知识,看了CSDN和博客园的几篇文章,有了一定的简单了解,决定根据个人理解整合一份随笔写下来,望诸位指教. 一:基础问题 1.首先需要知道了解什么是GC? GC如其名,就 ...
- GC垃圾回收机制,iOS内存管理。
问题: MRC中通过调用静态方法创建的新对象,不再使用时需要对其发送release消息吗? 不需要,因为约定静态方法创建的对象会自动将其放入自动释放池,即已对其发送autorelease消息,因此不可 ...
随机推荐
- Nodejs中npm install 命令的问题
在使用nodejs的npm包管理工具中碰到过许多个坑,在网上查了很久才解决,现在加以总结. 两种安装方式(本地安装,全局安装) 1.全局安装(npm install -g moduleName/npm ...
- python中如何将两个list合并成一个list,不用for语句
1, add 2, 用list的extend方法,L1.extend(L2),该方法将参数L2的全部元素添加到L1的尾部,例如: 3, 用切片(slice)操作,L1[len(L1):len(L1)] ...
- hasura graphql 角色访问控制
目前从官方文档以及测试可以看出不加任何header的请求访问的是所有的数据,对于具有访问 控制的请求需要添加请求头,实际生产的使用需要集合web hook 的实现访问控制. 参考配置 访问请求 目前数 ...
- 图形学习 Javascript 正则 regexper.com
regexper.com 可以很方便的显示出正则图示,方便学习正则. 比如正则 ^([a-zA-Z0-9+_-])+@([a-zA-Z_-])+(\.[a-zA-Z0-9_-])+ 一目了然,直观显示 ...
- Chrome 上传时打开对话框非常慢
Chrome 上传时打开对话框非常慢 先说解决方法,将 Chrome 中这个选项关闭,打开会飞快. 如果只是图片之类是不会的,但是有 zip apk 之类的就会慢. 主要原因还是 Chrome 太安全 ...
- [NOI2018]归程(可持久化并查集,Kruskal重构树)
解法一: 1.首先想到离线做法:将边和询问从大到小排序,并查集维护连通块以及每个连通块中所有点到1号点的最短距离.$O(n\log n)$ 配合暴力等可以拿到75分. 2.很容易想到在线做法,使用可持 ...
- highlight.js 设置行号
原文地址:highlight.js 设置行号 博客地址:http://www.extlight.com 一.背景 笔者在开发这套博客系统时使用 Editormd 作为 Markdown 编辑器,由于不 ...
- kafka速度为什么快
1. kafka 使用了 分区.分布式.leader/followere 的方式.分布式让 kafka 排除了单点故障,分区和分区复制让数据不丢失2. kafka 使用 zero copy 技术 (基 ...
- CentOS 6.5下安装Oracle 11g(转)
最近开始学习CentOS使用,做些记录. 参考文献:Cent OS 6_5(x86_64)下安装Oracle 11g 一.硬件要求 1.内存&swap Minimum:1 GB of RAM ...
- MPEG2-TS音视频同步原理
一.引言MPEG2系统用于视音频同步以及系统时钟恢复的时间标签分别在ES,PES和TS这3个层次中. 在TS 层, TS头信息包含了节目时钟参考PCR(Program Clock Reference ...