在堆里存放着java世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前需要知道哪些对象还存活,哪些对象已经死去。那怎么样去判断对象是否存活呢?  

  一、判断对象是否存活算法

  1、引用计数法

  实现思路:给对象添加一个引用计数器。每当有一个地方引用它时,计数器加1;引用失效时计数器减1。在任何时刻计数器为0的对象就是不可能再被使用的。

  优点:实现简单,效率高。

  缺点:很难解决对象之间的相互循环引用。

  2、可达性分析算法

  实现思路:通过GC Roots的对象作为起始点,从这些节点向下搜索,搜索走过的路径成为引用链,当一个对象到GC Root没有任何引用链相连时,则证明对象是不可用的。

  优点:可以很好的解决对象相互循环引用的问题。

  缺点:没想到

  二、在java中,哪些对象可以作为GC Roots呢?

  1、虚拟机栈(栈帧中的本地变量表)中引用的对象

  2、方法区中静态类属性和常量引用的对象

  3、本地方法栈中JNI(Native方法)引用的对象

  三、对象标记回收过程

  如果一个对象在可达性分析算法中是不可达的,那是不是这个对象就一定会被回收呢?

  答案是否定的,这些对象还有一次复活的机会。要真正宣告一个对象死亡,至少要经历两次标记过程:如果对象在进行可达性分析后发现没有与任何的GC Roots相连接的引用链,那它会被第一次标记,且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。在什么情况下不会执行对象的finalize方法呢?1、当对象没有覆盖finalize()方法。2、该对象的finalize()方法已经被虚拟机调用过。如果一个对象被判定为有必要执行finalize方法,那这个对象会被放置在一个F-Queue的队列中,等待虚拟机自己创建的一个低优先级的Finalizer线程去执行。finalize方法是这些对象逃脱死亡命运的最后一次机会,如果对象要在finalize中成功拯救自己,只要重新与引用链上的任何一个对象建立关联即可,譬如把自己赋值给某个变量或者对象的成员变量。那在第二次标记是它将被移除“即将回收”集合。否则就只能等待着回收了。

  但是,finalize方法运行代价高,不确定性大,无法保证各个对象的调用顺序。在日常开发中强烈不建议使用这个方法,如果需要有“关闭外部资源”之类的工作,使用try-finally或者其他方式都可以做得更好更及时。

  四、垃圾收集算法

  1、标记-清除算法

  实现思路:标记算法实现很简单,通过前面介绍的可达性分析算法标记所有需要回收的对象,然后统一回收所有被标记的对象。它是最基础的收集算法,后续的收集算法都是基于这种思路并对其不足进行改进而得到的。

  缺点:效率不高、产生内存碎片

  2、复制算法V1

  实现思路:将内存按容量划分为大小相等的两块,每次使用其中的一块。当一块的内存用完了,就将还存活的对象复制到另一块上面,然后再把已使用过的内存空间一次清理掉。这样每次都是针对整个半区的内存进行回收,不用考虑内存碎片问题。

  优点:简单高效、不会有内存碎片问题

  缺点:内存会缩小为原来一半,代价高

  3、复制算法V2(新生代采用的算法)

  实现思路:替代原来将内存一分为二的方案,将内存分为一块较大的Eden空间和两块较小的Survivor空间,每次Eden使用其中的一块Survivor。当回收时,讲Eden和Survivor中还存活的对象一次性赋值到另外一块Survivor空间上,最后清理掉Eden和刚才使用过的Survivor空间。HotSpot虚拟机默认Eden和Survivor的大小比例是8:1(研究表明,新时代中98%的对象是朝生夕死的),也就是每次新时代中可用内存空间为整个新时代容量的90%。只有10%的内存会被浪费。但是,如果存活的对象占用的内存大于新时代的10%怎么办?这就需要依赖其他内存(老年代)进行分配担保了。

  优点:改善了第二点中的缺点。

  4、标记-整理算法(老年代采用的算法)

   实现思路:过程与标记-清除算法一样,但后续步骤不是直接对可回收对象进行清理。而是让所有的对象都向一端移动,然后直接清理掉端边界以外的内存。

《深入理解Java虚拟机》读书笔记-垃圾收集器与内存分配策略的更多相关文章

  1. 深入理解Java虚拟机03--垃圾收集器与内存分配策略

    一.概述  哪些内存需要回收? 什么时候回收? 如何回收? 二.对象已死吗  1.引用计数算法  定义:给对象添加一个引用计数器,当增加一个引用时,加1,当一个引用时,减1; 缺陷:当对象之间互相循环 ...

  2. 深入JAVA虚拟机笔记-垃圾收集器与内存分配策略

    第三章:垃圾收集器与内存分配 问题:1.哪些内存需要回收 2.什么时候回收 3.怎么回收 回收方法区:

  3. 深入理解Java虚拟机笔记——垃圾收集器与内存分配策略

    目录 判断对象是否死亡 引用计数器算法 可达性分析算法 各种引用 回收方法区 垃圾收集算法 标记-清除算法 复制算法 标记-整理算法 分代收集算法 HotSpot算法实现 枚举根节点 GC停顿(Sto ...

  4. 《深入理解java虚拟机》笔记(6)内存分配与回收策略

    一.垃圾回收日志说明 [GC[DefNew: 7307K->494K(9216K), 0.0043710 secs] 7307K->6638K(19456K), 0.0044894 sec ...

  5. 《深入java虚拟机》读书笔记之垃圾收集器与内存分配策略

    前言 该读书笔记用于记录在学习<深入理解Java虚拟机--JVM高级特性与最佳实践>一书中的一些重要知识点,对其中的部分内容进行归纳,或者是对其中不明白的地方做一些注释.主要是方便之后进行 ...

  6. 深入理解Java虚拟机读书笔记2----垃圾收集器与内存分配策略

    二 垃圾收集器与内存分配策略 1 JVM中哪些内存需要回收?     JVM垃圾回收主要关注的是Java堆和方法区这两个区域:而程序计数器.虚拟机栈.本地方法栈这3个区域随线程而生,随线程而灭,随着方 ...

  7. 深入理解Java虚拟机 -- 读书笔记(1):JVM运行时数据区域

    深入理解Java虚拟机 -- 读书笔记:JVM运行时数据区域 本文转载:http://blog.csdn.net/jubincn/article/details/8607790 本系列为<深入理 ...

  8. 深入理解java虚拟机_第三章(上)----->垃圾收集器与内存分配策略

    1.  前言 这一版块内容比较多,分为两篇文章来做笔记.本文讲述上半部分垃圾收集部分;下一篇文章写内存分配部分. 概述 对象已死吗? 引用技术算法 可达性分析算法 再谈引用 两次标记 回收方法区 2. ...

  9. 深入理解java虚拟机----->垃圾收集器与内存分配策略(下)

    1.  前言 内存分配与回收策略 JVM堆的结构分析(新生代.老年代.永久代) 对象优先在Eden分配 大对象直接进入老年代 长期存活的对象将进入老年代 动态对象年龄判定 空间分配担保  2.  垃圾 ...

随机推荐

  1. [知了堂学习笔记]_JSON数据操作第1讲(初识JSON)

    一.认识JSON 什么是JSON? JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式..它基于 ECMAScript (w3c制定的js规 ...

  2. Python学习笔记4

    根据文件类型选择文件 文件 s s.split('.')[1] 即为文件后缀名,据此判断 输出执行后结果到指定文件 os.system('E:\\Learning\\python\\test_case ...

  3. 函数作用域中的this问题

    首先一起回顾下预解析和作用域吧: 预解析: 浏览器每读到一个script标签或function,先不执行任何代码,会先把整个代码快速的浏览一遍,然后从中 挑出 var 和 function两个关键字 ...

  4. 我的Markdown的利器——Markdown Here、有道云笔记、iPic

    Markdown逐渐成为大家文章编辑的首选,这里推荐两个比较冷门的Markdown工具. 用什么当做Markdown的主力工具? 网上有很多人推荐的Markdown的工具包括专业的Markdown工具 ...

  5. TFLearn构建神经网络

    TFLearn构建神经网络 Building the network TFLearn lets you build the network by defining the layers. Input ...

  6. poj 1679 Prim判断次短路

    题意:判断最短路是否唯一. 思路:先prrim一次求出最短路同时记录最短路加入的边: 然后枚举所求边,将其删除再求n-1次prim,判断再次所求得的最短路与第一次求得的次短路的关系. 代码: #inc ...

  7. PS小实验-去除水印

    PS小实验-去除水印 水印是一些品牌商覆盖在图片或视频上的一个商标logo或小文本,比如大家最讨厌的百度logo,作者本人也是比较讨厌水印的,让好端端的一张图片变得美中不足. 个人觉得用photosh ...

  8. RobotFramework安装完成后怎么在桌面显示ride图标

    安装了RobotFramework后,怎么让桌面上显示带有机器人的图标呢? 一.桌面上创建ride快捷方式 进入到python的安装目录的/Scripts目录下,找到ride.py文件-->右键 ...

  9. Java GUI+mysql+分页查询

    1.要求 : 创建一个学生信息管理数据库 2.实现分页查询 代码如下: a)学生实体类: /** * @author: Annie * @date:2016年6月23日 * @description: ...

  10. 201521123061 《Java程序设计》第七周学习总结

    201521123061 <Java程序设计>第七周学习总结 1. 本周学习总结 2. 书面作业 ArrayList代码分析 1.1 解释ArrayList的contains源代码 贴上源 ...