垃圾回收器检查托管堆中是否有应用程序不再使用的对象,如果有,他们使用的内存就可以回收(如果一次垃圾回收之后堆中仍然没有可用的内存,new操作符就会抛出一个OutOfMemoryException)。垃圾回收器如何知道应用程序正在使用一个对象呢?这个说起来比较复杂。

每个应用程序都包含一组根。每个根都是一个存储位置,其中包含指向引用类型对象的一个指针。该指针要么引用托管堆中的对象,要么为null,例如:类型中定义的任何静态字段被认为是一个根。除此之外,任何方法的参数和局部变量也被认为是一个根。只有引用类型的变量才能被认为成根;值类型的变量永远不被认为成根。

垃圾回收期开始执行时,它假设堆中所有对象都是垃圾,换句话说,它假设线程栈中没有引用堆中对象的变量,没有CPU寄存器引用堆中的对象,也没有静态字段引用堆中的对象。垃圾回收期第一阶段就是所谓的Marking(标记)阶段。垃圾回收期沿着线程栈上行检查所有根。如果发现一个根引用一个对象,就在对象的“同步块索引字段”上做一个标记。例如:垃圾回收器发现一个局部变量指向堆中的一个对象。下图展示了一个堆,其中包含几个已经分配的对象。应用程序的根直接引用对象A、C、D、F。

所有这些对象都以标记。标记对象D时垃圾回收期发现这个对象含有一个引用了对象H的字段,造成对象H也被标记。垃圾回收期就是这样,以递归的形式遍历所有可达的对象。

标记好根和他引用的字段之后,垃圾回收器检查下一个根,并继续标记对象。如果垃圾回收期试图标记一个先前标记过的对象。就会停止沿着这个路径走下去,这个行为有两个目的。首先垃圾回收期不会多遍历一组对象,所以性能能得到提升。其次,如果存在对象的循环链表,可以避免陷入无限循环。

检查好所有根之后,堆中将包含一组已标记的对象和未标记的对象。已标记的对象是通过应用程序可达的对象,而未标记的对象时不可达的,不可达的对象被认为是垃圾,他们占据的内存就可以回收,现在垃圾回收期开始第二个阶段压缩阶段。这个阶段垃圾回收器线性的遍历堆,以寻求未标记对象的连续内存块。如果发现的内存块比较小,垃圾回收期会忽略他们,如果发现的内存块比较大,垃圾回收器就会把非垃圾的对象移动到这里以压缩栈。

很自然,移动内存中的对象之后,包含指向这些对象中的指针变量将变的无效。所以垃圾回收期现在开始重现访问应用程序的根,并修改他们来指向新内存的地址。另外,如果对象中的字段指向的是另一个已移动的对象的字段,垃圾回收期也要负责修正这些字段的值。堆内存压缩之后,托管堆得NextObjPtr指针指向紧接在最后一个非垃圾回收之后的位置 ,下图是垃圾回收之后的托管堆。

如你所见,垃圾回收期造成显著的性能损失,这是使用托管堆得主要缺点。但是需要注意的是,垃圾回收期只有在0代已满的时候才回收。在此之前,托管堆得性能远远高于C运行时。最后,CLR的垃圾回收期提供了一些特殊的优化措施,可以大幅提高垃圾回收的性能。(后面讲说代的概念)

作为程序员,我们从前面的讨论中得出两个重要的认识。第一点,不必自己写代码来管理应用程序所用的对象的生存期。第二点,前面一章描素的bug将不复存在。首先,不可能再发生对象泄露的情况。因为任何对象只要应用程序没有根引用它,都会在某个时刻被垃圾回收期回收,所以应用程序不可能发生内存泄露的情况,另外应用程序也不可能再访问已经释放的对象。其次,不可能访问一个已经释放的对象。这是因为如果对象可达,就不会被释放;如果它不可达,应用程序就没办法访问它。另外,由于垃圾回收器导致了内存的压缩,所以托管对象不可能造成托管堆进程虚拟空间地址的碎片化。如果是非托管代码,地址空间的碎片化可能非常严重。但是使用托管堆是这个问题就不发生了,另外是在使用大对象的时候,托管堆仍然有可能碎片化。

转载于:https://www.cnblogs.com/bingbinggui/p/4379353.html

第二节:垃圾回收期算法简介相关推荐

  1. (王道408考研数据结构)第一章绪论-第二节2:算法的时间复杂度和空间复杂度

    文章目录 一:算法的时间复杂度 (1)事后统计方法 (2)事前分析估算的方法 (3)函数的渐进式增长 (4)算法时间复杂度 A:算法时间复杂度定义-大 O O O记法 B:推导大 O

  2. (王道408考研数据结构)第一章绪论-第二节1:算法的基本概念、算法的特性及设计要求

    文章目录 一:算法的基本概念 (1)数据结构和算法的关系 (2)算法(Algorithm)的定义 二:算法的特性 三:算法设计要求 程序=数据结构+算法,前面我们已经探讨了什么是数据结构,明白了如何用 ...

  3. 第二十讲 DES算法简介

    1 美国制定数据加密标准简况 目的:通信与计算机相结合是人类步入信息社会的一个阶梯, 它始于六十年代末,完成于90年代初.计算机通信网的形成与发 展,要求信息作业标准化,安全保密亦不例外.只有标准化, ...

  4. 垃圾回收之垃圾回收算法(标记清除、标记整理、复制)、分代垃圾回收

    2. 垃圾回收算法 之前我们学习了如何判断一个对象是不是可以作为垃圾被回收,但是具体回收还需要依赖一些回收方面的算法,常见的有三种: 分别是标记清除.标记整理.和复制这三种算法,下面先从第一种标记清除 ...

  5. (王道408考研操作系统)第三章内存管理-第二节3:页面置换算法2

    上接: (王道408考研操作系统)第三章内存管理-第二节2:页面置换算法1 文章目录 一:时钟置换算法(CLOCK) (1)简单时钟置换算法 (2)改进型时钟置换算法 二:页面置换算法总结 一:时钟置 ...

  6. 【数据聚类】第三章第二节2:K-Means算法及其Python实现(算法实现、结果展示)

    pdf下载(密码:7281) 本文上接:[数据聚类]第三章第二节1:K-Means算法及其Python实现(距离度量方式.目标函数和算法流程) 本文下接:[数据聚类]第三章第二节3:K-Means算法 ...

  7. Java虚拟机(十四)——垃圾回收算法

    文章目录 垃圾回收相关算法 标记阶段 引用计数算法 可达性分析算法(根搜索算法.追踪性垃圾收集) 基本思路: GC Roots 有哪几类? 注意 对象的finalization机制 清除阶段 标记-清 ...

  8. 数据结构与算法:算法简介

    数据结构与算法:算法简介 雪柯 大工生物信息 提笔为写给奋进之人 已关注 你说呢 . shenwei356 等 70 人赞同了该文章 引用自算法图解,作者[美] Aditya Bhargava 译袁国 ...

  9. 了解java虚拟机—垃圾回收算法(5)

    引用计数器法(Reference Counting) 引用计数器的实现很简单,对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1,当引用失效时,引用计数器减1.只要对象A的引用计数器的 ...

最新文章

  1. java 全角_Java全角、半角字符的关系以及转换
  2. javascript 【小数转百分数 保留两位小数】
  3. 浪潮K1 Power通过ISO/IEC 20243标准认证
  4. 实验1 查看cpu和内存,用机器指令和汇编指令编程
  5. 解决终端SSH连接服务器一段时间不操作之后卡死的问题
  6. Harmony OS — RadioButton RadioContainer单选按钮单选按钮组
  7. iOS开发的几种加密方式
  8. java double 初始化_java语言程序员之正确的初始化
  9. Ubuntu文件目录结构详解
  10. 风行python_Python是啥?竟然彻底改变了老板对我的看法……
  11. 精美UI界面欣赏[1]
  12. 计算机需要记笔记,如何优雅地用电脑记笔记
  13. 五岁的瑞幸:如何越坎重生?
  14. 网易互娱2017实习生招聘在线笔试第一场-2源代码编译
  15. 微信群控系统的实现原理,微信群控系统源码的核心实现代码
  16. 怎么用Java解二元方程_正则表达式解二元方程式代码
  17. 初学Python案例之一(开平方代码)
  18. 3D导航栏翻转(css)
  19. 2022年第十三届蓝桥杯大赛软件类决赛C/C++大学B组C题卡牌
  20. nvd3使用(1)——多线图中的一个很隐蔽的bug

热门文章

  1. html透明度_学好Web前端开发,必要了解的HTML+CSS的技巧有哪些
  2. 信息系统服务器数量设置,《系统下服务器设置与优化.doc
  3. spring cloud 集成consul
  4. python dataframe取一列_python - 从pandas DataFrame列标题中获取列表
  5. python3 安装pyinstaller_python3.7 打包(.exe)神器——pyinstaller 安装及用法
  6. python替换字符的操作_Python 字符串操作(string替换、删除、截取、复制、)
  7. python巡检脚本juniper_python实现巡检系统(solaris)示例
  8. python网络爬虫文献综述_python网络爬虫综述
  9. datagrid wpf 刷新数据_c# – WPF Datagrid-自动刷新
  10. ubuntu apt-get 默认下载路径