java虚拟机之垃圾回收篇

java虚拟机之内存模型篇
java虚拟机之垃圾回收篇
java虚拟机之垃圾收集器篇
java虚拟机之虚拟机类加载机制
java虚拟机之Java内存模型与线程

垃圾收集与内存分配策略

对象存亡

1.引用计数法

给对象添加一个引用计数器,每当有一个地方引用他,计数器就+1,引用失效计数器就-1,任何时刻计数器为0,就是不再使用的对象。这个方法在很多地方也确实在使用,但是 有个很难解决的问题就是对象之间的相互循环引用,比如a持有b的引用,b也持有a的引用,各自的计数器都是1所以无法回收。

2.可达性分析算法

这个算法就是通过一系列称为“gc root”的对象作为起点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到gc root没有任何引用链相连时,则证明此对象时不可用的。

可达性分析
** 可以作为“gc root”对象**

在这里插入图片描述

引用

强引用:“Object obj = new Object()” 只要强引用存在,gc永远不会回收被引用对象
软引用(SoftReference):有用但是非必须的对象,在系统要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收,如果还是没有足够的内存就发生oom。
弱引用(WeakReference):也是非必须对象,但是这个对象只能生存到下次垃圾收集发生之前,当gc的时候不管是否内存足够,都会回收掉只被弱引用关联的对象。
虚引用(幽灵引用,幻影引用):是最弱的引用关系,一个对象是否有虚引用存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例,这个的目的就是在垃圾回收它的时候得到一个通知。

注意 :即使不可达的对象,也不是“非死不可”,真正宣告一个对象死亡,至少需要两次标记过程,如果对象到gc root没有相连接引用链,那么就第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法或者finalize()方法已经被虚拟机调用过,那么就将这两种情况视为“没有必要执行”
如果被判定是有必要执行finalize()方法,那么这个对象将会放置一个F-Queue的队列中,稍后由一个由虚拟机自动建立的低优先级的finalizer线程去执行,但是并不承诺他会运行结束,这时候你如果想让对象不死亡,那么就让他有到gc root的引用链。

回收方法区

永久代的垃圾收集主要两部分内容:废弃常量和无用的类。

常量:没有任何String对象指向“abc”,也没有其他地方引用了这个字面量,如果这个时候gc就会回收掉这个对象。

无用的类:
A.该类的所有实例已经被回收,就是java堆中不存在该类的任何实例
B.加载该类ClassLoader已经被回收。
C.该类对象的java.lang.Class 对象没有任何地方被应用,无法在任何地方通过反射访问该类的方法。

垃圾收集算法

标记-清除算法

最基础的垃圾收集算法,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成之后统一回收掉所有被标记的对象。
标记-清除算法的缺点有两个:首先,效率问题,标记和清除效率都不高。其次,标记清除之后会产生大量的不连续的内存碎片,空间碎片太多会导致当程序需要为较大对象分配内存时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。

在这里插入图片描述
复制算法

将可用内存按容量分成大小相等的两块,每次只使用其中一块,当这块内存使用完了,就将还存活的对象复制到另一块内存上去,然后把使用过的内存空间一次清理掉。这样使得每次都是对其中一块内存进行回收,内存分配时不用考虑内存碎片等复杂情况,只需要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。
复制算法的缺点显而易见,可使用的内存降为原来一半。

在这里插入图片描述

注意: 现代商业虚拟机使用此种方式来回收新生代(分配一个较大的Eden,和两块较小的Survivor空间)

标记-整理算法

标记-整理算法在标记-清除算法基础上做了改进,标记阶段是相同的标记出所有需要回收的对象,在标记完成之后不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,在移动过程中清理掉可回收的对象,这个过程叫做整理。
标记-整理算法相比标记-清除算法的优点是内存被整理以后不会产生大量不连续内存碎片问题。
复制算法在对象存活率高的情况下就要执行较多的复制操作,效率将会变低,而在对象存活率高的情况下使用标记-整理算法效率会大大提高。
这个在老年代使用,因为对象存活率较高。
在这里插入图片描述

分代收集算法

根据内存中对象的存活周期不同,将内存划分为几块,java的虚拟机中一般把内存划分为新生代和年老代,当新创建对象时一般在新生代中分配内存空间,当新生代垃圾收集器回收几次之后仍然存活的对象会被移动到年老代内存中,当大对象在新生代中无法找到足够的连续内存时也直接在年老代中创建。

现在的Java虚拟机就联合使用了分代复制、标记-清除和标记-整理算法,java虚拟机垃圾收集器关注的内存结构如下:

在这里插入图片描述

Hotspot 算法实现

枚举根节点

可达性分析需要考虑下面两个点:

1.如果方法区大小就有数百兆,如果逐一检查引用,则肯定消耗性能,所以不可能这么做

2.在执行可达性分析时,必须要保证这个过程期间对象的引用关系不能再变化,否则不能保证分析结果正确性

必须要停止所有线程去执行枚举根节点,被称为Stop the World

解决方法

OopMap数据解构: 保存GC Roots 节点,避免全局扫描去一一查找。(目前主流java虚拟机都是准确式GC)

安全点: 精简指令,为特定位置(安全点: Safepoint)上的指令生成对应的OopMap,暂停进行GC的位置也是在安全点,在这个地方引用关系不会发生改变

GC发生时,让所有线程(不包括执行JNI调用的线程) 都“跑”到最近的安全点上再停顿:
抢先式中断(Preemptive Suspension) : GC发生时,中断全部线程,如果发现线程不在安全点,则恢复让其”跑” 到安全点
主动式中断(Voluntary Suspension ): 设置一个标志,然后采用轮询触发,就是线程跑到这里点的时候检查是否jvm有中断请求,如果是就挂起。

安全区域 :在这一段区域中,引用关系不会发生变化,在这个区域中的任意地方开始GC都是安全的。处理没有被分配CPU时间的线程。
当线程在sleep() , 或者blocked 的时候,这个时候线程是无法响应jvm的中断请求,让线程走到安全区域,然后挂起。
所以需要安全区域来处理,这个区域中,在这个区域中任意地方开始gc都是安全的,当线程指向到这个区域的时候,标识自己进入了safe region,当jvm gc的时候就不管进入了安全区域的线程了。线程要离开安全区域的时候,检查系统是否已经完成了根节点枚举(或者整个gc过程)。
我整理的文档下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为什么要学JVM1、一切JAVA代码都运行在JVM之上,只有深入理解虚拟机才能写出更强大的代码,解决更深层次的问题。2、JVM是迈向高级工程师、架构师的必备技能,也是高薪、高职位的不二选择。3、同时,JVM又是各大软件公司笔试、面试的重中之重,据统计,头部的30家互利网公司,均将JVM作为笔试面试的内容之一。4、JVM内容庞大、并且复杂难学,通过视频学习是最快速的学习手段。课程介绍本课程包含11个大章节,总计102课时,无论是笔试、面试,还是日常工作,可以让您游刃有余。第1章 基础入门,从JVM是什么开始讲起,理解JDK、JRE、JVM的关系,java的编译流程和执行流程,让您轻松入门。第2章 字节码文件,深入剖析字节码文件的全部组成结构,以及javap和jbe可视化反解析工具的使用。第3章 类的加载、解释、编译,本章节带你深入理解类加载器的分类、范围、双亲委托策略,自己手写类加载器,理解字节码解释器、即时编译器、混合模式、热点代码检测、分层编译等核心知识。第4章 内存模型,本章节涵盖JVM内存模型的全部内容,程序计数器、虚拟机栈、本地方法栈、方法区、永久代、元空间等全部内容。第5章 对象模型,本章节带你深入理解对象的创建过程、内存分配的方法、让你不再稀里糊涂。第6章 GC基础,本章节是垃圾回收的入门章节,带你了解GC回收的标准是什么,什么是可达性分析、安全点、安全区,四种引用类型的使用和区别等等。第7章 GC算法与收集器,本章节是垃圾回收的重点,掌握各种垃圾回收算法,分代收集策略,7种垃圾回收器的原理和使用,垃圾回收器的组合及分代收集等。第8章 GC日志详解,各种垃圾回收器的日志都是不同的,怎么样读懂各种垃圾回收日志就是本章节的内容。第9章 性能监控与故障排除,本章节实战学习jcmd、jmx、jconsul、jvisualvm、JMC、jps、jstatd、jmap、jstack、jinfo、jprofile、jhat总计12种性能监控和故障排查工具的使用。第10章 阿里巴巴Arthas在线诊断工具,这是一个特别小惊喜,教您怎样使用当前最火热的arthas调优工具,在线诊断各种JVM问题。第11章 故障排除,本章会使用实际案例讲解单点故障、高并发和垃圾回收导致的CPU过高的问题,怎样排查和解决它们。课程资料课程附带配套项目源码2个159页高清PDF理论课件1份89页高清PDF实战课件1份Unsafe源码PDF课件1份class_stats字段说明PDF文件1份jcmd Thread.print解析说明文件1份JProfiler内存工具说明文件1份字节码可视化解析工具1份GC日志可视化工具1份命令行工具cmder 1份学习方法理论部分推荐每天学习2课时,可以在公交地铁上用手机进行学习。实战部分推荐对照视频,使用配套源码,一边练习一遍学习。课程内容较多,不要一次性学太多,而是要循序渐进,坚持学习。      

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值