jvm - 垃圾回收算法
Posted 我的IT技术路
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jvm - 垃圾回收算法相关的知识,希望对你有一定的参考价值。
学习java的同学,避免不了要去了解jvm(java virtual machine),因为这是java最底层的基石,掌握了jvm,能够帮助我们更好的理解java语言。当我们去谈论java和c++的时候,一个很重要的区别就是垃圾回收,C++在创建对象之后,一定要去释放,而java语言会自动将垃圾进行回收。本系列文章总结学习jvm笔记,参考的书籍是:《深入理解java虚拟机-第3版》,需要说明的是:该书主要描述的是hot-spot虚拟机,openjdk和sun/oracle Jdk都是默认使用该虚拟机。由于个人能力有限,文中难免有理解不到位的地方,还请留言指导,在此谢过。
本文主要说明的是jvm回收算法,注意区分垃圾回收算法和垃圾回收器。回收算法是理论上的,回收器是实际开发出来的。在了解垃圾回收算法之前,先熟悉一下哪些会被定义成垃圾。
Jvm垃圾判断方法
在我们谈论垃圾的时候,可能需要了解的是,jvm是怎么判定一个对象是不在被使用了。只有当对象不在被使用了,我们才能回收该对象。在判定一个对象是否还存活的方法常见的有两种:引用计数法和链路可达性分析。
引用计数法:该方法在判断对象是否存活的问题上是这样设计的:为每一个对象添加一个引用计数器,每当对象被其他地方引用时计数加1,对象的引用失效时计数减1。当引用计数器减到0的时候,认为该对象可以被回收。不过,该方案在某些问题上比较棘手,比如常说的相互引用问题,A,B对象互相引用,除此之外,没有其他引用了,此时两个对象的引用计数器都为1,但实际上两个对象都应该被回收。
链路的可达性分析:该方法的判定依据是:通过一系列称为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过 程所走过的路径称为“引用链”(Reference Chain),如果某个对象到GC Roots没有任何链路,就认为该对象不可用。目前java就是基于此实现的,那现在就有一个问题了,哪些是根节点?Java目前规定的根节点有以下几类:
栈里面的引用对象
静态属性引用对象
常量引用对象
本地方法栈引用的对象
synchronized锁持有的对象
虚拟机的内部引用对象
虚拟机内部回调和缓存的引用对象
垃圾回收器临时加入的引用对象
Java四种引用
在java语言中,有四种引用分别是强引用,软引用,弱引用,虚引用。下面分别就四中引用的一些常见的特点进行分析如下表:
引用类型 |
创建方式 |
回收时间 |
使用场景 |
结合引用队列 |
强引用 |
new Object() |
不回收 |
平时对象创建 |
不使用 |
软引用 |
new SoftReference<T> |
没有内存时 |
图片编辑器 |
在回收后加入引用队列 |
弱引用 |
new WeakReference<T> |
下一次垃圾回收 |
WeakHashmap threadLocal |
在回收后加入引用队列 |
虚引用 |
New PhantomReference<T> |
下一次垃圾回收 |
垃圾回收器 |
在回收前加入引用队列 |
JVM垃圾回收算法:
上面我们描述了jvm是怎么判定对象可以被回收,现在我们在看一下垃圾回收的算法有哪些?垃圾回收算法是一种理论上的方案,和真正的垃圾回收器还是有差别的。常见的垃圾回收算法有三种:标记清除算法,标记整理算法,标记复制算法。
标记清除:第一步先对所有对象进行标记是否存活,第二步将不存活的对象进行清理。
标记整理:第一步先对所有对象进行标记是否存活,第二步将存活的对象往空间一端移动,第三步清理掉边界之外的内存。
标记复制:第一步将内存分为大小相等的两块,每次只使用其中的一块,第二步标记使用的那块存活的对象,第三步将存活的对象拷贝到另一边,第四步清除掉之前使用的一边。
下面我们对三种算法进行一个对比总结:
回收算法 |
优点 |
缺点 |
使用场景 |
标记清除 |
响应时间快 |
内存碎片化 |
CMS老年代收集器 |
标记整理 |
吞吐量高 |
响应时间较长 |
ParallelScavenge老年代收集器 |
标记复制 |
响应时间快 |
空间使用率低 |
基本上收集器新生代收集 |
上面的表格说明了新生代的收集算法基本上是标记复制算法,而老年代则根据需求来决定使用标记清除还是标记整理算法。如果是追求响应时间短采用标记清除,如果追求吞吐量采用标记整理算法。
这样的话,会让应用停顿的时间较长。而如果不进行整理,大量的碎片化内存就需要更为复杂的内存分配器和内存访问器来解决。内存的访问是应用程序最频繁的操作,如果增加内存分配器的负担,到最后必然会导致吞吐量下降。(吞吐量的计算公式是:用户代码执行时间/(用户代码执行时间+垃圾回收时间) )
要完成垃圾回收主要考虑的三件事情:哪些是垃圾?什么时候回收?怎么回收。本文描述的是哪些是垃圾并且怎么回收的理论指导-垃圾回收算法。通过本文我们了解到判定垃圾的两种方法和三个基本垃圾回收算法。下一文我们会详细介绍几种常用并且面试常问的垃圾收集器。
本文的内容就这么多,如果你觉得对你的学习和面试有些帮助,帮忙点个赞或者转发一下哈,谢谢。
以上是关于jvm - 垃圾回收算法的主要内容,如果未能解决你的问题,请参考以下文章