本文主要介绍“Java GC的相关问题有哪些”。在日常操作中,相信很多人对Java GC的相关问题有所怀疑。边肖查阅了各种资料,整理出简单易用的操作方法,希望能帮助大家解答“Java GC有哪些相关问题”的疑惑!接下来,请和边肖一起学习!
Java GC
目标
当遇到一个问题或者一个知识点的时候,我们要明白,明白要解决什么问题。说到Java GC,这个GC的目的是什么?显然是为了回收内存,因为内存是有限的。随着程序中创建的对象越来越多,如果回收,内存会越来越大,最后程序会出现异常。既然目的是回收内存,一个新的问题就出现了。哪些物品可以回收?什么时候回收?如何回收?
哪些对象可以被回收
简单来说,无用的物品是可以回收的。换句话说,如果定义一个对象是无用的呢?这里主要有两种方法,一种叫做引用计数法,另一种叫做可达性分析法。
引用计数
引用计数意味着如果一个对象被另一个对象引用一次,该对象将有一个引用计数器,并且该计数器将增加一。如果释放,参考计数器将递减1。当引用计数器的计数为0时,表示该对象没有用,此时可以回收该对象。表面上看起来合情合理,容易实施,但仔细一想就会发现有问题。例如,如果对象A引用对象B,但对象B也引用对象A,那么此时对象A和对象B的引用计数器的计数不会为0,但这两个对象不会被其他对象引用。理论上,这两个物体是可以回收的。
从上面可以看出,这个方案是有问题的,会导致内存泄漏。然后又来了一个方案,就是可达性分析。
可达性分析
可达性分析是指从GCRoots的点往下搜索,当找不到引用链时,说明对象是垃圾。那么哪些对象可以被认为是根节点呢?Java栈中有对象,方法区有静态属性和常量,局部方法栈中有对象。依次从这些对象中向下搜索。如果未能到达根节点的对象是垃圾对象,则可以回收它们。
如下图所示,对象A、B、C可以找到与Roots节点的连接,但对象D、E、F找不到与Roots节点的连接,即无法到达,所以这三个对象是垃圾对象。
什么时候回收
以上两个方案解决了哪些物件可以回收,那么下一个问题就是什么时候回收?当排除人工调用时,垃圾收集总是在为新对象分配内存时发生。此时,如果内存空间不足,将触发垃圾收集。
怎么回收
我们知道哪些物品可以回收,什么时候应该回收,那么下一个问题就是如何回收。根据不同的实现方式,垃圾收集有许多不同的算法。例如,有标签移除算法、复制算法、标签排序算法和世代回收算法。以下是简要介绍。想了解更多的人可以自己研究。
标记清除算法
标记算法简单易懂,主要执行两个动作,一个是标记,另一个是清除和回收标记对象内存。这种算法的一个问题是会有严重的内存碎片。如下图所示:
从上图可以看出,内存回收后内存碎片严重,导致在分配一些大对象时内存不足,但整体内存确实足够。
复制算法
复制算法的实现简单明了,就是把内存任意分成两部分,平时使用时只固定其中一部分。当需要GC时,幸存的对象被复制到另一部分,然后所有使用的内存被清理。下图:
从上图可以看出,清除标记的内存碎片问题已经解决,但很明显复制算法还有另一个问题,那就是内存利用率大幅下降,可用内存只有原来的一半。
标记整理算法
既然去除标记和复制算法各有优缺点,我们自然要思考这两种算法能否结合,于是出现了标记整理算法。标记阶段与标记算法相同,其中首先标记要回收的零件,
不过清除阶段不是直接清除,而是把存活的对象往内存的一端进行移动,然后清除剩下的部分。如下图:
标记整理的算法虽然可以解决上面两个算法的一些问题,但是还是需要先进行标记,然后进行移动,整个效率还是偏低的。
分代回收算法
分代回收算法是目前使用较多的一种算法,这个不是一个新的算法,只是将内存进行的划分,不同区域的内存使用不同的算法。根据对象的存活时间将内存的划分为新生代和老年代,其中新生代包含 Eden 区和 S0,S1。在新生代中使用是复制算法,在进行对象内存分配的时候只会使用 Eden 和 S0 区,当发生 GC 的时候,会将存活的对象复制到 S1 区,然后循环往复进行复制。当某个对象在进行了 15 次GC 后依旧存活,那这个对象就会进入老年代。老年代因为每次回收的对象都会比较少,因此使用的是标记整理算法。
垃圾回收器
讲完了垃圾回收算法,我们再看下垃圾回收器,每一种垃圾回收器都是不同时代的不同产物,都有其独特性。
-
Serial 垃圾收集器(单线程、复制算法)
-
ParNew垃圾收集器(Serial+多线程)
-
Parallel Scavenge 收集器(多线程复制算法、高效)
-
SerialOld收集器(单线程标记整理算法)
-
ParallelOld收集器(多线程标记整理算法)
-
CMS收集器(多线程标记清除算法)
-
G1收集器
各个垃圾收集器的配合使用情况可以参考下图,个人觉得对这么多的收集器没有必要全部精通,可以注重关注一下 CMS 和 G1 就可以了。感兴趣的小伙伴可以自己的研究一下。
到此,关于“有哪些Java GC的相关问题”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/64471.html