.NET 垃圾回收浅解
在说明垃圾回收的实现机制之前,先说明一下垃圾回收存在的背景。
垃圾回收器(GC)是.NET平台中一个很重要的组成部分,.NET垃圾回收机制降低了编写程序的复杂程度,使程序员不用耗费精力去处理析构,成功的将内存管理从程序的编写时,脱离到运行时。
一、析构函数
析构函数的作用主要是释放类在构造函数中以及类生命周期中所获取的资源,比如需要释放互斥锁、由操作符NEW所分配的对象内存等。当然析构函数也不只限于释放资源,一般析构函数可以执行在最后一次操作对象后所需要执行的任何操作。
二、关于垃圾回收
在.NET FRAMEWORK框架中,内存中的资源(二进制信息)分为“托管资源”和“非托管资源”,其中托管资源必须受到CLR的管理(如强类型安全检查),非托管资源需要手动释放。
托管资源分别存放在两个地方,一个是“堆栈”,另外一个是“托管堆”。值类型和引用类型的引用存放在“堆栈”中,而引用类型所代表的对象存在于“托管堆”中。
三、垃圾回收算法
CLR中的每个对象有两个开销字段:类型对象指针,同步块索引。
(1)、对于对象生存期的管理,有的系统采用“引用计数算法”,而对于微软的COM用的就是此算法。具体算法就是每个对象都在维护着一个内存字段,用来统计有多少个位置在使用该对象,当某一个位置不在使用该对象后,该内存字段中的计数就减一,直至该字段最后为0,当值为0时,该对象就可以从内存中删除掉了。
但是该算法最大的问题就是处理不好循环引用。
(2)、CLR使用的算法为“引用跟踪算法”,此算法只关心引用类型的变量,因为只有这种变量才能引用堆上的对象。可以将引用类型的变量称为根。
此算法是当CLR进行GC时,首先暂停所有线程,以防止线程CLR在检查期间访问对象并更改其状态。
A、CLR遍历堆中的所有对象,并将同步块索引字段中的一位设为0,这表明所有对象可以被删除。
B、查看所有活动根,并查看它们引用了哪些对象。如果一个根包括NULL,则忽略此根继续检查下一个根。
C、如果某根引用了堆上的对象,则会标记此对象,在该对象的同步块索引中的位设为1。此对象被标记后,CLR会检查这个对象中的根,标记它们引用的对象。若发现对象已经标记,则不再重新检查该对象,也就避免了因为循环引用而产生死循环。
D、检查完毕后,堆中的对象要么被标记,要么未被标记,然后CLR进入GC的“压缩”阶段。(需要注意的是,静态字段引用的对象会一直存在,直到用于加载类型的APPDOMAIN卸载为止。内在泄漏的一个重要原因就是静态字段引用某个对象集合,然后不停的向对象集合添加数据项。所以,要尽量避免使用静态字段。)
四、代的机制
CLR的GC是基于代的垃圾回收器,对于垃圾回收做了以下假设:
1、对象越新,生存期越短。
2、对象越老,生存期越长。
3、回收堆的一部分,速度快于回收整个堆。
五、垃圾回收触发条件
1、当CLR检测到第0代超过内存预算时,则触发一次GC。
2、代码显式调用GC的静态方法Collect。大多时候要避免使用此方法。从第2代开始回收。
3、当使用CreateMemoryResourceNotification或者QueryMemoryResourceNotification来监视系统的总体内存使用情况时,如果Windows报告内存低,则CLR会强制垃圾回收以释放死对象,减小进程工作集。
4、CLR卸载APPDOMAIN时,CLR会认为一切都不是根。
5、CLR正在关闭,Windows将会回收进程中的全部内存。
六、垃圾回收模式
有两种基本GC模式:工作站、服务器。应用程序默认使用以“工作站”GC模式运行。若想使用服务器回收器,可以在配置文件中添加gcServer元素(gcServer=true)。
另外还有两种子模式:并发(默认)和非并发。一般并发垃圾回收器消耗的内存通常比使用非并发垃圾回收器多。若要使用非并发回收器,可在配置文件中创建gcConcurrent元素(enable=false)
七、需要特殊清理的类型
针对一些本机资源的终结,CLR除了回收对象内存之前,还需要在Finalize中释放本机资源,如下所示:
- public class sometype()
- {
- ~sometype()//此为一个finalize方法
- }
需要注意的是,finalize方法的执行时间是控制不了的。同时,CLR不保证多个finalize方法的调用顺序,在finalize方法中最好不要访问定义了finalize方法的其他类型的对象。调用静态方法也要小心。由于此方法是为释放本机资源而设计的,所以要谨慎使用。
如果想创建封装了本机资源的类型时,需要继承Safehandle。
另外一种释放本机资源的方法是Dispose,调用此方法只是控制这个清理动作的发生时间。同时,调用此方法并不会将托管对象从托管堆中删除。若决定显示调用Dispose方法,建议将调用放在一个异常处理finally块中。
.NET 垃圾回收浅解的更多相关文章
- Java虚拟机之垃圾回收详解一
Java虚拟机之垃圾回收详解一 Java技术和JVM(Java虚拟机) 一.Java技术概述: Java是一门编程语言,是一种计算平台,是SUN公司于1995年首次发布.它是Java程序的技术基础,这 ...
- 基于Python对象引用、可变性和垃圾回收详解
基于Python对象引用.可变性和垃圾回收详解 下面小编就为大家带来一篇基于Python对象引用.可变性和垃圾回收详解.小编觉得挺不错的,现在就分享给大家,也给大家做个参考. 变量不是盒子 在示例所示 ...
- python 垃圾回收详解
原文:https://zhuanlan.zhihu.com/p/31150408 总纲 策略和垃圾回收系统工作内容 引用计数详解 标记-清除+分代收集 循环引用 编程应用-常见方法 ex 过程详解 使 ...
- C# using垃圾回收详解
简介 定义一个范围,将在此范围之外释放一个或多个对象. 语法 using (Font font1 = new Font("Arial", 10.0f)) { } C# 语言参考 主 ...
- JVM垃圾回收详解
通常,我们在写java程序的时候,似乎很少关注内存分配和垃圾回收的问题.因为,这部分工作,JVM已经帮我们自动实现了. 这样看起来,好像很美好,但是任何事情都有两面性.虽然JVM会自动的进行垃圾回收, ...
- Python垃圾回收详解:引用计数+标记清理+分代回收
Python采用的是引用计数机制为主,标记-清理和分代收集两种机制为辅的策略. 1.引用计数 python中一切皆对象,所以python底层计数结构地就可以抽象为: 引用计数结构体{ 引用计数; 引用 ...
- JVM中GC浅解:垃圾回收的了解
1.为什么要有GC 没有GC的世界,我们需要手动进行内存管理,但是内存管理是纯技术活,又容易出错.但是我们写码的目的是为了解决业务问题,所以可以把这种纯技术活自动化,当然自动化也是有代价的. 2.垃圾 ...
- Java Garbage Collection基础详解------Java 垃圾回收机制技术详解
最近还是在找工作,在面试某移动互联网公司之前认为自己对Java的GC机制已经相当了解,其他面试官问的时候也不存在问题,直到那天该公司一个做搜索的面试官问了我GC的问题,具体就是:老年代使用的是哪中垃圾 ...
- JVM的垃圾回收机制详解和调优
JVM的垃圾回收机制详解和调优 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存.java语言并不要求jvm有gc,也没有规定gc如何工作.不过常用的jvm都有gc,而且大多数gc都 ...
随机推荐
- Using the JDBC Driver
Download JDBC Driver This section provides quick start instructions for making a simple connection t ...
- D02——C语言基础学PYTHON
C语言基础学习PYTHON——基础学习D02 20180801内容纲要: 1 字符串的系列操作 2 集合 3 文件的读写 4 字符编码转换 5 小结 6 练习:三级菜单(有彩蛋) 1 字符串的系列操 ...
- ownCloud问题处理server replied 423 Locked to
打开owncloud 数据库备份:oc_file_locks表(备份免错哦)然后清空该表,客户端同步一次,故障解决 owncloud大的数据无法同步..
- Spark构成
RDD Spark基本的数据结构叫弹性分布式数据集(Resilient Distributed Datasets,简称RDD). 概念: 一个分布于集群节点的只读数据集合,并以容错的.并行的方式进行维 ...
- 【CF1157F】Maximum Balanced Circle 求一个相邻元素之间绝对值为小于1的最大环
题目: https://codeforces.com/contest/1157/problem/F 给出一个序列 , 我们要从序列里面挑出一些数构造成一个相邻元素之间绝对值为小于1的最大环 , 挑选的 ...
- Kali/Ubuntu无法和物理机之间复制粘贴解决办法
Vmware安装Linux,传统的vmtools已经被抛弃,当前建议使用Open-VM-tools 安装Open-VM-tools//Kali,Ubuntu: sudo apt install Ope ...
- spring boot快速入门 7: 使用aop处理请求
样例:登陆拦截(aop简单样例) 第一步:在pom 文件中加入aop依赖 <!-- spring aop --> <dependency> <groupId>org ...
- javac的Resolve类解读
方法1:isInitializer() /** An environment is an "initializer" if it is a constructor or * an ...
- JavaScript数据结构-2.排序算法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- WPF获取程序版本号(Version)的方法
1.第一种:通过System来获取 public static Version GetEdition() { return System.Reflection.Assembly.GetExecutin ...