C#内存管理与垃圾回收
垃圾回收还得从根说起,就像生儿育女一样。
根:根是一个位置,存放一个指针,该指针指向托管堆中的一个对象,或是一个空指针不指向任何对象,即为null。根存在线程栈或托管堆中,大部分的跟都在线程栈上,因为定义的变量就存在线程栈上,类型对象指针存在托管堆中,因为实例化一个对象要额外分配两个字段“类型对象指针”和“同步块索引”。
类型对象指针的作用。实例化一个对象并没有为其方法分配内存,类型的静态字段分配内存,而实例要向调用属于类型的一些东西,就必须通过类型对象指针。如对象的实例是共用类型的方法,实例只需要通过类型对象指针调用类型的方法,更多关于方法的调用请看我的这篇博客。
同步块索引的作用。1:用于lock,使对象在同一时刻只能一个线程访问;2:用于获取对象的hashCode;3:在垃圾回收时标志某个对象是否是垃圾。关于lock最经典的一个例子就是单例了,大家的实现都是实例化一个object对象,然后锁住它,然后在判断是否要实例要实现单例的那个对象。我们为什么要实例化一个object,而不是直接lock(typeof(object)),那是因为这样会把object这个类型给锁住,锁住期间,任何使用线程使用lock(typeof(object))就必须等待,object还是可以正常使用。lock能起到单线程访问的原因是:它里面有一个空的for死循环,一直在读同步块索引中的一个位,如果这个位没有被标志跳出循环,如果被标志就一直执行循环,直到方法执行完成,其他线程就一直等待,现在你知道lock能使你的程序只能单线程反问也知道lock的效率低了吧。
NextObjPtr一个最牛B的指针。CLR中的所有资源都从托管堆中分配,托管堆是一块连续的内存空间,维护一个指针NextObjPtr,它指向上一个对象地址的后面,下一个对象的开始位置,若托管堆中没有对象就指向托管堆的开始位置,每分配一个对象就将NextObjPtr指向这个对象的后面,以准备开始分配下一个对象。NextObjptr指针移动的位置其实就是上一个对象所在空间的长度,从指向对象的开始位置改为对象的末尾吗。从哪里开始分配对象就全靠NextObjPtr啦。
实例化一个对象需要多少空间?对象的所有字段所需的内存+类型对象指针+同步块索引。关于类型对象指针和同步块索引的作用前面已经提过了。有些字段没有明显定义,但它确确实实存在,每个对象除了object的对象都有base字段,通过它可以调用父类的实例字段和方法,通过它你可以访问你爷爷的爷爷定义的字段和方法。CLR用递归的方式调用父类的方法,当然也要看,你爷爷是否愿意让你调用,原因你懂的。
在垃圾回收开始之前速度比C快。对象就这样开心的在托管堆中分配,托管堆的容量是有限的,总有一天第0代会满,容不下一粒沙子。垃圾回收就出场了,在垃圾回收出场之前,你使用内存很happy,当然速度是非常快,比C语言的速度还快,因为C的内存是随便分配,只要找到合适大小的区域,就在那里分配内存了,这样会导致内存碎片,有时需要一块大的内存,需要遍历多处。垃圾回收的时候日子就不是那么好过了。速度肯定比C慢了,看下面你就知道垃圾回收的时候,程序的速度为什么慢了。
垃圾回收分两步:1:标记;2:压缩
1:标记。在垃圾回收开始的时候,垃圾回收器视托管堆中的所有对象都为垃圾,即线程栈上没有指针指向托管堆。这样的估计是因为一个对象被视为垃圾就是它没有被引用,当垃圾回收开始的时候,垃圾回收器会沿着线程栈线性扫描,当线程栈上的一个变量引用了托管堆中的对象时,垃圾回收器就会将这个对象标记,即修改该对象同步块索引中的一个特定的位,同步块索引就是一个bit数组,每一个元素都有它特定的作用,上面就列出了我所知道的三个功能。被标记的对象也可能引用其他的对象,而被引用的对象同样会被标记,垃圾回收器是用递归的方式将这些对象一一标记的,一个对象可能会被多个对象引用,当垃圾回收器发现某个对象被标记时就会退出递归,因为再往下递归完全是多余,而且还可能出现死循环。
垃圾回收器就这样线性的扫描线程栈,递归的扫描托管堆,最后将托管堆中所有被引用的对象标记,而没有被标记的对象就是垃圾,等着被回收。
2:压缩。当垃圾被回收之后,就会出现磁盘碎片,那么就要对托管堆进行整理,即压缩。将没有被回收的对象放在一起,靠近托管堆开始的位置,将剩余的内存腾出空间来以便存放新的对象。由于压缩很多对象就会移动位置,而引用他们的指针都会变得无效,所以托管堆要修改所有指针的指向,以保证不会因为垃圾回收而让对象变得不可到达,指针变得无效。
压缩完了之后,又腾出了空间,又可以分配新的对象,当第0代满了之后又进行垃圾回收,垃圾回收就这样一直进行着,直到回收了3代还是没有内存可以分配,那就是弹尽粮绝的时候了,CLR会告诉你OutOfMemoryException。CLR的内存被的程序吃光了。更多关于代的信息,可以看我的这篇博客。在第0代满的时候就会进行垃圾回收,第0代回收完之后还是没有足够的内存存放当前对象就回收第1代,如果还是不够就回收第2代,够就不回收下一代,垃圾回收还可以用代码控制GC.Collect()。
更多关于内存管理和垃圾回收的内容,请等待我的下一篇博客。
C#内存管理与垃圾回收的更多相关文章
- 使用虚幻引擎中的C++导论(四-内存管理与垃圾回收)(终)
使用虚幻引擎中的C++导论(四)(终) 第一,这篇是我翻译的虚幻4官网的新手编程教程,原文传送门,有的翻译不太好,但大体意思差不多,请支持我O(∩_∩)O谢谢. 第二,某些细节操作,这篇文章省略了,如 ...
- Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收
很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...
- Java内存管理和垃圾回收
笔记,深入理解java虚拟机 Java运行时内存区域 程序计数器,线程独占,当前线程所执行的字节码的行号指示器,每个线程需要记录下执行到哪儿了,下次调度的时候可以继续执行,这个区是唯一不会发生oom的 ...
- javascript中的内存管理和垃圾回收
前面的话 不管什么程序语言,内存生命周期基本是一致的:首先,分配需要的内存:然后,使用分配到的内存:最后,释放其内存.而对于第三个步骤,何时释放内存及释放哪些变量的内存,则需要使用垃圾回收机制.本文将 ...
- 面试题之C# 内存管理与垃圾回收
面试题之C# 内存管理与垃圾回收 你说说C# 的内存管理是怎么样的 这句话我记了一个多礼拜了, 自从上次东北师大面试之后, 具体请看<随便扯扯东北师大的面试>. 国庆闲着没事, 就大概了解 ...
- JVM内存管理及垃圾回收【转】
很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...
- .NET基础 (05)内存管理和垃圾回收
内存管理和垃圾回收1 简述.NET中堆栈和堆的特点和差异2 执行string abc="aaa"+"bbb"+"ccc"共分配了多少内存3 ...
- JVM原理(Java代码编译和执行的整个过程+JVM内存管理及垃圾回收机制)
转载注明出处: http://blog.csdn.net/cutesource/article/details/5904501 JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.e ...
- java Vamei快速教程22 内存管理和垃圾回收
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 整个教程中已经不时的出现一些内存管理和垃圾回收的相关知识.这里进行一个小小的总结. ...
随机推荐
- 大数据系列(1)——Hadoop集群坏境搭建配置
前言 关于时下最热的技术潮流,无疑大数据是首当其中最热的一个技术点,关于大数据的概念和方法论铺天盖地的到处宣扬,但其实很多公司或者技术人员也不能详细的讲解其真正的含义或者就没找到能被落地实施的可行性方 ...
- 深入解析SQL Server并行执行原理及实践(上)
在成熟领先的企业级数据库系统中,并行查询可以说是一大利器,在某些场景下他可以显著的提升查询的相应时间,提升用户体验.如SQL Server, Oracle等, Mysql目前还未实现,而Postgre ...
- 【C++】输入多行数字到数组
前天做某公司笔试题的时候,其输入格式是多行数字,每行以空格为分隔符,以换行符号为结束输入到多个数组.在JAVA中有相应的函数直接将一行拆成数组,感觉在C++中这中输入方式还是挺奇怪的,今天想出一种解决 ...
- 用html5 js实现浏览器全屏
项目中需要将后台浏览器的窗口全屏,也就是我们点击一个按钮要实现按F11全屏的效果. 在HTML5中,W3C制定了关于全屏的API,就可以实现全屏幕的效果,也可以让页面中的图片,视频等全屏目前只有goo ...
- log4j 不同模块输出到不同的文件
1.实现目标 不同业务的日志信息需要打印到不同的文件中,每天或者每个小时生成一个文件.如,注册的信息打印到register.log,每天凌晨生成一个register-年月日.log文件, 登录信息的日 ...
- 一致性算法RAFT详解
原帖地址:http://www.solinx.co/archives/415?utm_source=tuicool&utm_medium=referral一致性算法Raft详解背景 熟悉或了解 ...
- Oracle 数据库基础——安装
一.数据库基础知识 1.概念 数据库全称数据库管理系统,简称DBMS,是一种在计算机中,针对数据进行管理.存储.共享的一种技术. 2.分类 数据库的发展过程中,按逻辑模型可分为以下几种: 3.关系型数 ...
- 怎样制作FL Studio步进音序器中的节奏
了解了FL Studio一些操作功能后,我们就要去用这些操作功能完成我们想要的作品.所以今天小编就来带领大家在FL Studio的步进音序器中制作出简单的节奏,与此同时大家也会了解到通道的几个基础功能 ...
- struts2案例
Struts 2是一个MVC框架,以WebWork框架的设计思想为核心,吸收了Struts 1的部分优点.Struts 2拥有更加广阔的前景,自身功能强大,还对其他框架下开发的程序提供很好的兼容性.下 ...
- POJ2104 K-th Number[主席树]【学习笔记】
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 51440 Accepted: 17594 Ca ...