JVM7:垃圾回收是什么?从运行时数据区看垃圾回收到底回收哪块区域?垃圾回收如何去回收?垃圾回收策略,引用计数算法及循环引用问题,可达性分析算法

这篇具有很好参考价值的文章主要介绍了JVM7:垃圾回收是什么?从运行时数据区看垃圾回收到底回收哪块区域?垃圾回收如何去回收?垃圾回收策略,引用计数算法及循环引用问题,可达性分析算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

垃圾回收是什么?从运行时数据区看垃圾回收到底回收哪块区域?

在Java中,垃圾回收(Garbage Collection,简称GC),是自动管理内存的机制。它负责检测不再使用的对象,并释放它们所占用的内存,以供其他对象使用。
JVM7:垃圾回收是什么?从运行时数据区看垃圾回收到底回收哪块区域?垃圾回收如何去回收?垃圾回收策略,引用计数算法及循环引用问题,可达性分析算法,jvm,算法,java,jvm
JVM内存模型认识的差不多了,就应该思考,什么样的内存模型适合什么样的GC策略,包括垃圾回收为什么会出现。实际上,很多东西都是相对应版本的JVM强加上去的。那么垃圾回收是什么?到底回收哪块区域?如何去回收?

这个时候观察运行时数据区来进行分析。
线程私有的区域是完全没有必要回收的,因为方法消亡就消亡了,它的生命周期很短,会伴随着你的方法的退出而消亡,因此不必关心它的回收,而且类文件结构确定之后,就知道整个方法当中字节码指令流转的一个情况了,所以不需要对这块区域进行关心。

线程共享的区域是方法区和堆这两块区域,而方法区MetaSpace中,实际上它的回收有没有呢?有的,但是很少,或者说回收的效率并不高,因为方法区当中的数据是静态变量,常量,字符串常量池,类信息,即时编译后的代码,它的生命周期一般都很长,随着程序运行一段时间之后,它占用方法区的那一块内存会趋于稳定,因为这些东西不回收,所以回收重点关注的地方还是这个区域。因为Java是一门面向对象的一门高级语言,所以对象的创建以及回收才是最重要的。而我们的GC,或者说所谓的垃圾回收,更多的是对于堆内存这块区域的回收,来进行讨论。

那么堆要进行回收的话,到底要怎么去进行回收呢?

垃圾回收如何去回收?

首先需要考虑的第一个问题:什么样的场景下适合使用什么样的垃圾回收策略。
这里注意策略和算法是不一样的,算法是真正落地的实现,而策略不一定要落地。

回收策略按照我们的思想去设计优化的话,首先肯定要关注内存的使用情况,因为垃圾回收本身就是一种穷人策略,因为没有那么多内存共我们去挥霍,所以才会想尽办法提高我们垃圾回收的效率。

垃圾回收策略

  • 收的多: 收的多,意味着收的久。尽可能每次多回收一些对象,尽可能多腾出一些内存,而收的多意味着收的久。
  • 收的快: 收的快,意味着每次收的少需要多次回收。最好可以将时间缩短到一次网络延迟,哪怕回收次数很多都可以容忍,这样收再多次都是无所谓的。

因此会在垃圾回收的时间上和CPU的效率上有个抉择,假设CPU使用率过高,那么可以尽可能的去调低垃圾回收的一个频率,使得CPU的使用率能够在我们接受的范围内,也就是可控性回收

比如我们平时收拾屋子,那么首先就是确定屋子多大,然后哪些东西是垃圾。程序亦是如此,hotsport的开发者也会有这样的想法,它需要有一套判断当前对象是垃圾的依据(或者叫算法)。那么在程序当中,所有的执行逻辑、判断逻辑都可以称之为算法,因为程序就是逻辑+数据组成的。

为什么回收选取操作性较高的数据?
举个例子,你在家里扫垃圾,肯定也是选择比较容易清理的哪些东西叫做垃圾,不好拿的和好拿的肯定先选好拿的。那么在当前的场景中,我们操作性较高的数据是对象,因此是根据对象去进行一个讨论。

而在Java中,引用和对象显然是有关联的,如果要操作对象,必然是会引用来去执行,那么这个时候,最显然的一个办法就是通过引用计数来判断对象是否可以回收,简单的来说,如果一个对象没有任何与之相关联的引用,即它们的引用计数都为0的情况下,也就是说,这个对象没有任何场景下可能会使用到它了,那这个对象就是可回收对象,这就是引用计数法。但是现在Java主流算法并不是这个,因为它难以解决循环引用的问题。

引用计数算法及循环引用问题

/**
 * 引用计数法难以解决循环引用问题
 */
public class CircularReferenceDemo {

    public static void main(String[] args) {

        CircularReferenceObject obj1 = new CircularReferenceObject();
        CircularReferenceObject obj2 = new CircularReferenceObject();
        /**
         * 这两句代码表示:
         * 第一步:虚拟机栈有两个东西obj1、obj2,它是虚拟机栈中的局部变量表中的元素
         * 第二步:new两个CircularReferenceObject对象,这两个对象是不同的CircularReferenceObject实例,在堆当中共开辟两个内存地址
         * 第三步:obj1指向堆中的实例1,obj2指向堆中的实例2
         *
         * 此时此刻,堆中的这两个实例的引用计数应该各自+1=1
         */

        obj1.instance = obj2;
        obj2.instance = obj1;
        /**
         * 让堆中的两个实例互相引用,obj1指向obj2,obj2指向obj1
         *
         * 此时此刻,堆中的这两个实例的引用计数应该各自再+1=2
         */

        obj1 = null;
        obj2 = null;
        /**
         * 赋值为null,表示不再指向任何数据,即栈中元素不再指向堆中实例
         *
         * 此时此刻,堆中的这两个实例的引用计数应该各自-1=1
         *
         * 这个时候,循环引用问腿就来了:按照引用计数法,堆中这两个实例各自的引用计数都不为0,也就是说这两个实例所占用的堆内存空间无法释放
         *
         * 系统给到实例内存空间但是无法释放的这种情况称之为内存泄露,如果这种情况一直发生,最终会导致内存溢出,因此主流的JVM已经摒弃了这种算法
         */
    }

    static class CircularReferenceObject {
        public Object instance = null;
    }
}

JVM7:垃圾回收是什么?从运行时数据区看垃圾回收到底回收哪块区域?垃圾回收如何去回收?垃圾回收策略,引用计数算法及循环引用问题,可达性分析算法,jvm,算法,java,jvm
对于对象之间的循环引用问题,其实引用计数法它会有策略进行解决,但是这个不是Java应该关心的事情。Java中已经摒弃了引用计数法这种算法,python还在用,引用计数法这种算法的效率会比另一种算法快的多,既然主流的JVM已经摒弃了这种算法,那么必然会出现一种新的算法对它进行替代,来解决循环引用的问题,最少也是让所谓循环引用的问题带来的影响没那么大,那么另一种算法横空出世,就是可达性分析算法。

可达性分析算法

可达性分析算法,也被称为根搜索算法,目前主流的JVM都是采用的这种算法,比如Sun公司的hotsport。
这个算法的核心是从所谓的GC root进行出发,也就是从一个所谓的根进行出发,利用数学中的图论(Graph Theory)知识,从根触发,单条引用链能够到达的对象,便是存活对象,反之即为不可达对象,不可达对象就是需要回收的垃圾。

这里面涉及到两个概念根(所谓的GC root)和可达性。所谓的根、GC root只是一种引用,它并不是对象,它只是告诉你地址,让你知道如何找对象。

哪些可以作为GC root的对象?

  • 虚拟机栈中的局部变量表中的元素Object obj = new Object();,这种new出来的对象,必然是我们需要的对象,所以obj这种位于虚拟机栈中的局部变量表中的元素必然可以作为GC root
  • 方法区的静态变量以及常量
  • 本地方法栈JNI中的元素

思考

引用到底是什么?不同引用会有什么作用?不同引用会不会有不同的监控策略?如果可达性分析算法标记为不可达会立即进行垃圾回收吗?常说的标记整理又是做什么的?

汇总

JVM1:官网了解JVM;Java源文件运行过程、javac编译Java源文件、如何阅读.class文件、class文件结构格式说明、 javap反编译字节码文件;类加载机制、class文件加载方式

JVM2:类加载机制、class文件加载方式;类加载的过程:装载、链接、初始化、使用、卸载;类加载器、为什么类加载器要分层?JVM类加载机制的三种方式:全盘负责、父类委托、缓存机制;自定义类加载器

JVM3:图解类装载与运行时数据区,方法区,堆,运行时常量池,常量池分哪些?String s1 = new String创建了几个对象?初识栈帧,栈的特点,Java虚拟机栈,本地方法发栈,对象指向问题

JVM4:Java对象内存布局:对象头、实例数据、对齐填充;JOL查看Java对象信息;小端存储和大端存储,hashcode为什么用大端存储;句柄池访问对象、直接指针访问对象、指针压缩、对齐填充及排序

JVM5:JVM内存模型与运行时数据区的关系,堆为什么分区,分代年龄,Young区划分,Survivor区为什么分为S0和S1,如何理解各种GC:Partial GC、Full GC、Young GC

JVM6:JVM内存模型验证;使用visualvm查看JVM视图;Visual GC插件下载链接;模拟JVM常见错误,模拟堆内存溢出,模拟栈溢出,模拟方法区溢出

JVM7:垃圾回收是什么?从运行时数据区看垃圾回收到底回收哪块区域?垃圾回收如何去回收?垃圾回收策略,引用计数算法及循环引用问题,可达性分析算法

JVM8:引用是什么?强引用,软引用,弱引用,虚引用,ReferenceQueue引用队列;对象生命周期有哪些阶段?创建、应用、不可见、不可达、收集、终结、对象空间重分配;重写finazlie方法弊端

JVM9:STW:stop the world,什么时候会垃圾回收?垃圾收集算法:标记清除算法、标记复制算法、标记整理算法;清除算法的整理顺序:任意顺序,滑动顺序;什么是分代收集算法?

JVM10:JVM参数分类,JVM标准参数,JVM非标准参数,-X参数,-XX参数,其他参数;查看JVM参数,idea控制台输出JVM参数,单位换算;设置JVM参数的常见方式;常用JVM参数及含义

JVM11:垃圾收集器的并发和并行,Serial,Serial Old,ParNew,Parallel Scavenge,Parallel Old,源码分析CMS两种模式,CMS如何定位可达对象?文章来源地址https://www.toymoban.com/news/detail-674772.html

到了这里,关于JVM7:垃圾回收是什么?从运行时数据区看垃圾回收到底回收哪块区域?垃圾回收如何去回收?垃圾回收策略,引用计数算法及循环引用问题,可达性分析算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JVM——JVM 垃圾回收

    本节常见面试题 问题答案在文中都有提到 如何判断对象是否死亡(两种方法)。 简单的介绍一下强引用、软引用、弱引用、虚引用(虚引用与软引用和弱引用的区别、使用软引用能带来的好处)。 如何判断一个常量是废弃常量 如何判断一个类是无用的类 垃圾收集有哪些算

    2024年02月12日
    浏览(28)
  • 【JVM】JVM 垃圾回收算法

    目前JVM中有三种常见的垃圾回收算法,分别是:标记清除、标记整理和复制,这三种垃圾回收算法各有优缺点,下面逐一介绍。 在读本篇文章中,如果对JVM中哪个是垃圾,哪个不是垃圾,JVM到底是怎么知道的,请先读下面这篇文章 【JVM】JVM 判断对象存活算法(引用计数算法

    2024年02月09日
    浏览(40)
  • 【JVM】11. 垃圾回收及回收算法算法

    2023年05月29日
    浏览(56)
  • JVM的组件、自动垃圾回收的工作原理、分代垃圾回收过程、可用的垃圾回收器类型

    https://www.processon.com/diagraming/64c8aa11c07d99075d934311 https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html 年轻代是所有新对象被分配和老化的地方。当年轻代填满时,这会导致minor garbage collection,minor gc会回收掉很多的游离对象。游离的年轻代很快就被收集起来。一些幸存的

    2024年02月14日
    浏览(39)
  • JVM基础(3)——JVM垃圾回收机制

    作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 学习必须往深处挖,挖的越深,基础越扎实! 阶段1、深入多线程 阶段2、深入多线程设计模式 阶段3、深入juc源码解析

    2024年01月25日
    浏览(34)
  • JVM基础(5)——JVM垃圾回收算法

    作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 学习必须往深处挖,挖的越深,基础越扎实! 阶段1、深入多线程 阶段2、深入多线程设计模式 阶段3、深入juc源码解析

    2024年02月02日
    浏览(34)
  • JVM垃圾回收——G1垃圾收集器

    目录 一、什么是G1垃圾收集器 二、G1垃圾收集器的内存划分 三、G1垃圾收集器的收集过程  四、G1收集器的优缺点 五、G1收集器的JVM参数配置         Garbage First(简称G1)收集器是垃圾收集器技术发展史上里程碑式的成果,它摒弃了传统垃圾收集器的严格的内存划分,而是采

    2024年02月05日
    浏览(35)
  • 【Java】图解 JVM 垃圾回收(一):GC 判断策略、引用类型、垃圾回收算法

    垃圾 是指运行程序中 没有任何引用指向的对象 ,需要被回收。 内存溢出 :经过垃圾回收之后,内存仍旧无法存储新创建的对象,内存不够溢出。 内存泄漏 :又叫 “ 存储泄漏 ”,对象不会再被程序使用了,但是 GC 又不能回收它们。例如:IO 流不适用了但是没有被 Close、

    2024年02月19日
    浏览(37)
  • 浅谈JVM垃圾回收机制

    新生代收集(Minor GC/Young GC):只对新生代进行垃圾收集 老年代收集(Major GC/Old GC):只队老年代进行垃圾收集 混合收集(Mixed GC):对整个新生代和老年代进行垃圾收集 收集整个Java堆和方法区 空间分配担保是为了确保在Minor GC之前老年代还有容纳新生代所有对象的剩余空间 垃圾回收算

    2024年02月10日
    浏览(35)
  • JVM及垃圾回收机制

    类加载器负责将.class文件加载到JVM中。主要分为三种层次:Bootstrap ClassLoader、Extension ClassLoader和Application ClassLoader。它们按层次关系加载类,保证类的隔离性和重用性。 运行时数据区包括方法区、堆、栈、本地方法栈和程序计数器。堆用于存放对象实例,方法区保存类信息和

    2024年02月12日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包