1 为什么要使用垃圾回收机制?

“垃圾收集”暗示程序不再需要的对象就是垃圾,可以被丢弃。更精确,更新的说法是“内存回收”。

1.1 新对象的使用

当一个对象不再被程序所引用时,他所使用的堆空间可以被回收,以便于被后续的新的对象使用。垃圾回收必须能判断哪些对象是不再被引用的,并且能够把他们所占据的堆空间释放出来,在释放不再被引用的对象的过程中,垃圾收集器运行将要被释放的对象的终结方法(finalizer)

1.2 处理堆碎片

除了释放不再被引用的对象之外,垃圾收集器还要处理堆碎片。堆碎片实在正常程序运行过程中产生的。新的对象分配了空间,不再被引用的对象被释放,所以堆碎块的空间位置介于活动的对象之间。请求分配新对象时可能不得不增大堆空间的大小,虽然可以使用的总空间是足够的。因为,堆中没有连续的空闲放得下新的对象。在一个虚拟机内存系统中,增长的堆所需要的额外分页(或交换)空间会影响运行程序的性能。

1.3 使用垃圾收集的有点和缺点

优点:把用户从释放占用内存的重担中解放出来

在一定程序上帮助程序保持完整性(是java安全策略一个重要的组成部分)

缺点:加大了程序的负担,可能会影响性能。虚拟机在追踪哪些对象被正在执行的程序所引用,并且动态的终结不再被使用的对象。和明确释放不再被使用的内存比起来,这个活动会需要更多的CPU时间。

2 垃圾收集算法

任何垃圾收集算法都必须完成俩件事情,首先,他必须检测出垃圾对象。其次,他必须回收垃圾对象所使用的堆空间并且还给程序。

垃圾检测通常通过建立一个根对象的集合并且检查从这些根对象开始的可触及性来实现。(可触及性:如果正在执行的程序可以访问到的根对象和某个对象之间存在引用路径)。对于程序来说,根对象总是可以被访问的。从这些根对象开始,任何可以被触及的对象都被认为是“活动”的对象。无法触及的对象被认为是垃圾,因为他们不再影响程序的未来执行。

  区分活动对象和垃圾的基本方法是引用计数和跟踪。

2.1 引用计数收集器

  在这种方法中,堆中每一个对象都有一个引用计数。当一个对象呗创建了,并且指向该对象的引用被分配了一个变量,这个对象的引用计数被置为1。当其他任何变量被赋值为对这个对象的引用时,计数加1.当一个对象的引用超过了生存期或者被设置一个新的值时,对象的引用计数减1。任何引用计数为0的对象都可以当成垃圾进行回收。当一个对象被垃圾收集的时候,他引用的任何对象计数值减1。这种方法中,一个对像被垃圾回收之后可能会导致后续其他对象的垃圾收集行动。

  优缺点:可以很快的执行,交织在程序的运行之中。这个特性对于程序不能被长时间打断的实时环境很有利。坏处就是,引用计数无法检测出循环(俩个对象或者更多对象的相互引用)。目前该技术已经不为人接受了

2.2 跟踪收集器

  跟踪收集器追踪从根节点开始的对象引用图。在追踪过程中遇到的对象以某种方式打上标记。总的来说,要么在对象本身设置标记,要么用一个队里的位图来设置标记。当追踪结束时,未被标记的对象就知道是无法触及的,从而被收集。

  基本的追踪算法被称作“标记并清除”。在标记阶段,垃圾收集器遍历引用树,标记每一个遇到的对象。在清除阶段,未被标记的对象被释放,使用的内存被返回到正在执行的程序。清除步骤 必须包括对象的终结。

2.3 压缩收集器

  这种方法用来简化消除堆碎块的工作,但是每一次对象访问都会带来性能的损失。

  标记并清除收集器通常使用的俩种策略是压缩和拷贝。这俩种方法都是快速的移动对象来减少碎块。压缩收集器吧活动的对象越过空间滑动到堆的一端,在这个过程中,堆的另一端就会出现一个大的连续空闲区,所有被移动的对象的引用会被更新,指向新的位置。

2.4 拷贝收集器

  拷贝收集器吧所有的活动对象移动到一个新的区域。再考呗过程中,他们紧挨着布置,所以可以消除原本他们在就区域的空隙。原有的区域被认为都是空闲区。这种方法的好处是对象可以在从跟对象开始的遍历过程中随着发现而被拷贝,不再有标记和清除的区分。

  一般的拷贝收集器算法被称为“停止并拷贝”。

2.5 按代收集的收集器

  在非常早的时候,我们看到过许多“分配慢”的意见 —— 因为就像早期 JVM 中的一切一样,它确实慢 —— 而性能顾问提供了许多避免分配的技巧,例如对象池。(公共服务声明:除了对最重量的对象之外,对象池现在对于所有对象都是严重的性能损失,而且要在不造成并发瓶颈的情况下使用对象池也很需要技巧。)但是,从 JDK 1.0 开始已经发生了许多变化;JDK 1.2 中引入的分代收集器(generational collector)支持简单得多的分配方式,可以极大地提高性能。

  特征:

1) 大多数程序所创建的大部分对象都只有很短的生命周期
2) 大多数程序都创建一些具有非常长生命周期的对象

  按代收集的收集器通过把对象按照寿命来分组解决这个效率低下的问题,更多的收集那些短暂出现的年幼对象,而非寿命较长的对象。在这种方法里,堆被划分为两个或者更多的子堆,每一个子堆为一“代”对象服务。最年幼的那一代进行最频繁的垃圾收集。因为大多数对象都是短促出现的,只有很小部分的年幼对象可以在它们经历第一次收集后存活。如果一个最年幼的对象经历了好几次垃圾收集后仍然存活,那么这个对象就成长为寿命更高的一代;它被转移到另外一个子堆中去。年龄更高的每一代的收集都没有年轻的那一些来的频繁。每当对象在它所属的年龄层(代)中变得成熟(逃过了多次垃圾收集)之后,它们就被转移到更高的年龄层中去。

2.6 自适应收集器

自适应收集器利用如下事实:在某种情况下某些垃圾收集算法工作的更好,而另外一些收集算法在另外的情况下工作更好。自适应算法监视堆中的情形,并且对应的调整为合适的垃圾收集技术。核心在于不同的情况下,使用这些算法最擅长的场景使用。

3 火车算法

垃圾收集算法和明确释放对象比起来有一个潜在的缺点,即垃圾收集算法中程序员对安排CPU时间进行内存回收缺乏控制。

火车算法是分代收集器所用的算法,目的是在成熟对象空间中提供限定时间的渐进收集。那么为什么要使用渐进收集呢?因为大范围的垃圾回收会占用大量的资源和时间,可能会导致暂停和无法满足系统实时性的要求,因此使用渐进收集。

车厢,火车和火车站

火车算法把成熟对象空间划分为固定长度的内存块,算法每次在一个块中单独执行。每个块属于一个集合。

块被叫车厢,集合被叫做火车,成熟对象空间是火车站。

火车被排序,块被附加到火车的尾部

这种方式表示出了成熟对象空间内所有块的总体排序。

车厢收集

火车算法执行的时候,要么收集最小数字火车中的最小数字车厢,要么收集整个最小数字火车。

如果整个火车都是垃圾对象,那么整个火车都被收集。否则,收集最小数字车厢。

收集最小数字车厢时,如果发现该车厢内部有被其他车厢引用对象则会转移到引用的车厢,如此循环,最后收集整个车厢。

收集最小数字火车时,如果发现该火车内有被其他火车引用对象则会转移到引用的火车,如此循环,最后收集整个火车。

记忆集合和流行对象

为了促进收集过程,火车算法使用了记忆集合。一个记忆集合是一个数据结构,包含所有对一节车厢或者一列火车的外部引用。一个空的记忆集合表明车厢或者火车中的对象都不再被车厢或者火车外的任何变量引用,可以被垃圾收集。

转载于:https://www.cnblogs.com/myadmin/p/5798524.html

java基础知识系列---垃圾收集相关推荐

  1. JAVA基础知识系列---进程、线程安全

    1.1 临界区 保证在某一时刻只有一个线程能访问数据的简便方法,在任意时刻只允许一个线程对资源进行访问.如果有多个线程试图同时访问临界区,那么在有一个线程进入后,其他所有试图访问临界区的线程将被挂起, ...

  2. Java基础知识系列之-抽象abstract

    1.何为抽象 抽象类往往用来表征我们在对问题领域进行分析. 设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象,我们不能把它们实例化(拿不出一个具体的东西)所以称之为抽象. 比 ...

  3. 23篇大数据系列(一)java基础知识全集(2万字干货,建议收藏)

    大数据系列爽文,从技术能力.业务基础.分析思维三大板块来呈现,你将收获: ❖ 提升自信心,自如应对面试,顺利拿到实习岗位或offer: ❖ 掌握大数据的基础知识,与其他同事沟通无障碍: ❖ 具备一定的 ...

  4. 跳槽者、应届生必看JAVA面试题系列 - JAVA基础知识(四)

    一: 前言 莫等闲,白了少年头,空悲切. 二: 面试挑战   在文章开始前,首先安利下"面试挑战": 凡是满足下面的挑战条件的,如果一个月内没有拿到一个Offer的,免费提供简历封 ...

  5. 超详细的Java面试题总结(二)之Java基础知识篇

    系列文章: 超详细的Java面试题总结(一)之Java基本知识 超详细的Java面试题总结(二)之Java基础知识篇 超详细的Java面试题总结(三)之Java集合篇常见问题 超详细的Java面试题总 ...

  6. Java基础知识第二讲:Java开发手册/JVM/集合框架/异常体系/Java反射/语法知识/Java IO

    Java基础知识第二讲(Java编程规范/JVM/集合框架/异常体系/Java反射/语法知识/Java IO/码出高效) 分享在java学习及工作中,常使用的一些基础知识,本文从JVM出发,讲解了JV ...

  7. Java基础看jvm,JAVA基础知识|java虚拟机(JVM)

    一.JVM简介 java语言是跨平台的,兼容各种操作系统.实现跨平台的基石就是虚拟机(JVM),虚拟机不是跨平台的,所以不同的操作系统需要安装不同的jdk版本(jre=jvm+类库:jdk=jre+开 ...

  8. 【转】Java基础知识整理

    本博文内容参考相关博客以及<Java编程思想>整理而成,如有侵权,请联系博主. 转载请注明出处:http://www.cnblogs.com/BYRans/ PDF版下载链接:<Ja ...

  9. Java基础知识总结(一)

    <Java基础知识总结>系列是对自己学习Java历程中知识的一个总结,也是为自己找工作前知识的回顾,为找工作奠定基础. 1.Identifiers:标识符 ①Names of class, ...

最新文章

  1. 教你如何防范远程桌面协议(RDP)的安全威胁
  2. 【php】windows安装PHP5.5+Apache2.4
  3. 低代码开发初体验一分钟——Jeecg-Boot 在线报表开发
  4. java awt jar_【Java学习笔记】操作JAR文件
  5. 以xml格式发送外部系统交易错误_在知行EDI系统中实施SNIP验证
  6. 打印工资条怎么做到每个人都有表头明细_快速制作工资条的方法
  7. TEXT部分文字颜色的改变
  8. Mobi格式的书籍整理
  9. 深入理解android虚拟机
  10. PhotoShop CC 2017软件工具面板使用---快速选择工具
  11. 微信的JS接口安全域名设置+tomcat服务器
  12. oracle11g在linux7的静默安装脚本
  13. 如何修改MySQL监听IP地址
  14. centos搭建mysql、nginx、nodejs、screen
  15. 软件工程技术--第六章 软件实现
  16. .NET 6 实现滑动验证码(七)、生成验证码
  17. 32位eclipse使用64位jdk问题
  18. 【判断蜂蜜真伪的简单方法】
  19. 关于windows10家庭中文版最近更新后无法使用共享打印机
  20. java 朗读_java下载安装 用Java实现简单的语音朗读

热门文章

  1. 让一个非窗口组件(non-windowed component)可以接受来自Windows的消息
  2. 转:巧用搜狗输入法输入英文单词
  3. Oracle实用技巧
  4. java多线程总结一:线程的两种创建方式及优劣比较
  5. C语言计算分段函数pta,PTA浙大版《C语言程序设计(第3版)》题目集 练习2-11 计算分段函数[2] (10分)...
  6. 多线程之间共享的资源有哪些
  7. c++组合 聚合 关联
  8. 使用VS2012内建的C++测试架构进行单元测试
  9. python histo 改变 bins 大小_在Python中显示具有非常不均匀的bin宽度的直方图
  10. as转html5工具,将keras的h5模型转换为tensorflow的pb模型