在堆里存放着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. postman 第1节 安装启动(转)

    安装: 1.mac app安装 浏览器访问https://www.getpostman.com/apps,选择Get the Mac App,下载安装即可 2.chrome app安装 浏览器访问ht ...

  2. Ubuntu部署可视化爬虫Portia2.0环境

    部署portia环境官方文档给出的方法太过简单,对于初学者来说是很难根据那一两行字成功部署portia环境的.对于部署portia这只可爱的爬虫的过程还是有很多坑的,主要写一篇portia2.0版本的 ...

  3. Linux平台 Oracle 12cR2 RAC安装Part2:GI配置

    Linux平台 Oracle 12cR2 RAC安装Part2:GI配置 三.GI(Grid Infrastructure)安装 3.1 解压GI的安装包 3.2 安装配置Xmanager软件 3.3 ...

  4. HTML添加样式三种办法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. 理解 angular 的路由功能

    相信很多人使用angular 都是因为他路由功能而用的 深入理解ANGULARUI路由_UI-ROUTER 最近在用 ionic写个webapp 看到几个demo中路由有好几种,搞的有点晕,查下资料研 ...

  6. hdu 6194 沈阳网络赛--string string string(后缀数组)

    题目链接 Problem Description Uncle Mao is a wonderful ACMER. One day he met an easy problem, but Uncle M ...

  7. java开发3轮技术面+hr面 面经(MT)

    一直没打理博客园  发现博客园阅读量好大,就把前段时间写的一个面经也搬过来咯,大家一起加油.... 作者:小仇Eleven 链接:https://www.nowcoder.com/discuss/37 ...

  8. Windows noinstall zip 安装MySQL。

    听完数据库老师的课,想在Windows下通过命令行的方法安装MySQL5.7,于是开了这个坑,终于把这个坑填上了. 第一步:下载MySQL 的noinstall zip ,点击该链接下载,或者复制链接 ...

  9. 如何解决xshell中无法输入中文的问题

    自从安上了xshell以后,用着那叫一个顺手,美中不足的就是一直无法输入中文.不过,既然学习IT,就要习惯英文嘛~直到--我遇到了脚本,写好一个脚本,必要的注释是少不了的,但是作为一个英文渣渣,我真的 ...

  10. 团队作业10——复审和事后分析(Beta版本)

    团队作业10--事后分析(Beta版本) http://www.cnblogs.com/newteam6/p/6953992.html 团队作业10--复审(Beta版本) http://www.cn ...