了解 JVM - 认识垃圾回收机制与类加载过程


前言

本篇通过介绍JVM是什么,认识JVM的内存区域的划分,了解类加载过程,JVM中垃圾回收机制,从中了解到垃圾回收机制中如何找到存活对象的方式,引用计数与可达性分析的方式,再释放垃圾对象时使用的方式,标准清除,复制算法,标准整理,分代回收等等,如有错误,请在评论区指正,让我们一起交流,共同进步!


文章目录

  • 前言
    • 1. 什么是JVM?
    • 2. 认识JVM内存区域的划分
    • 3. 认识类加载过程
    • 4. 类加载中的双亲委派模型
    • 5. JVM中的垃圾回收机制
      • 5.1 GC是什么?
      • 5.2.1 **第一阶段**:找GC对象,看对象是否存活; - 找垃圾
      • 5.2.2 第二阶段:释放垃圾对象
      • 5.3 JVM的分代回收机制
  • 总结

本文开始

1. 什么是JVM?

JVM: Java虚拟机,通过软件模拟具有硬件功能,运行在一个完全隔离的环境中的完整计算机系统;

2. 认识JVM内存区域的划分

JVM内存区域图示:

在这里插入图片描述

问题:查看变量的形态,也就是根据代码判断属于堆,栈还是方法区?
① 堆: 成员变量;(new 出来的对象存放其中)
② 栈:局部变量;(维护方法直接的调用关系)
③ 方法区:静态变量;(放类加载后的类对象, 被static修饰的)
【注】变量处在什么区域与变量类型无关;

线程私有的内存:每个线程都有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储;

  • 栈包括本地方法栈和虚拟机栈;
    本地方法栈:给JVM内部本地方法使用;
    虚拟机栈:给java代码使用;
  • 程序计数器:记录当前程序执行到那个指令了;
  • 堆:存储程序中创建的对象
  • 方法区:存放类加载后的类对象;- 静态变量;

【注】线程共享:堆与元数据区; 线程私有:栈(包括虚拟机栈,本地方法栈)与程序计数器;

例如:

	void function() {Student s = new Student();}//s是引用类型,是局部变量,处在栈上,而new Student()是对象,处在堆上;

3. 认识类加载过程

类加载:把 .class 文件加载到内存 得到类对象的过程;

类加载过程:
加载:找到.class文件,读取文件内容;
验证:验证.class文件是否符号规范要求;.class文件有明确的数据格式;
准备:给类对象分配内存空间(给类变量(static修饰的静态变量)分配的内存空间是未初始化,默认全是0,此时静态变量也是0);
例如:public static int value = 66; //此时准备是给value分配空间,初始化为0,不是66;
解析:针对字符串常量进行初始化;
初始化常量的过程: Java 虚拟机将常量池内的 符号引用 替换为 直接引用 的过程;
符号引用:处于相对位置,字符串常量在.class文件中存在,这时只知道他们之间的相对位置也就是符号引用;
直接引用:处于实际位置,加载到内存中知道位置就是实际内存位置也就是直接引用;
初始化:针对类对象进行初始化;(初始化静态成员,执行静态代码,类有父类也需要加载父类)

4. 类加载中的双亲委派模型

4.1 触发类加载时机 - 类加载是非必要,不加载
1)创建了类的实例
2)使用类的静态方法/静态属性
3)使用子类,触发父类的加载

4.2 双亲委派模型
双亲委派模型作用:在类加载阶段,找.class文件;

JVM加载类会使用类加载器这里简单介绍一下;
JVM中内置的三个类加载器:
① BootStrap ClassLoader: 负责加载Java标准库中的类
② Extension ClassLoader: 负责加载一些非标准的 Sun/Oracke扩展的库中的类;
③ Application ClassLoader: 负责加载项目中自己写的类,和第三方库中的类;

类加载过程图:

在这里插入图片描述

5. JVM中的垃圾回收机制

5.1 GC是什么?

GC是垃圾收集的意思;帮助程序员自动释放内存的;

JVM主要释放哪个区域? =》释放 堆区域

5.2 垃圾回收的两个阶段

5.2.1 第一阶段:找GC对象,看对象是否存活; - 找垃圾

如何找垃圾:Java中使用对象,只能通过引用,所以通过判断一个对象是否有引用指向就可以了;所以引入下面两种方法;

  • 引用计数法:给对象里安排一个额外空间,保存一个整数,表示该对象有几个引用指向;Java中不使用, Python,PHP使用

图示:在这里插入图片描述
【注】
计数器作用:引用增加,计数器就增加;引用减少,计数器就减少,当计数器为0时,就认为该对象没有引用了,认为时垃圾;
引用计数的缺点:
① 浪费空间 ② 存在循环引用的情况,会导致引用计数判定逻辑错误;

  • 可达性分析法:(Java中使用)把对象之间的引用关系,理解为一个树形结构,从一些特殊起点出发,进行遍历,只要能遍历到的对象,就是可达的,把不能访问到的对象,也就是不可达的当作垃圾;

通过一个树形结构图来看一下:

在这里插入图片描述
通过root引用作为起点,就可以访问整个树的节点;
可达性条件:进行图示遍历需要有起点;
① 栈上的局部变量,都是起点;
② 常量池中的引用对象;
③ 方法区中,静态成员引用的对象;
可达性分析的缺点:
1)消耗更多时间,遍历过程消耗时间,不能第一时间发现某个垃圾对象;
2)在遍历的时候,如果过程中当前代码的对象引用关系变了,就会产生麻烦;

5.2.2 第二阶段:释放垃圾对象

三种策略:
1)标记清除:先标记出回收对象,再直接释放垃圾对象内存;
产生问题:会产生大量内存碎片;清理完垃圾对象产生大量内存碎片,剩余的内存空间即使很多,但都是碎片化的,如果要申请一段连续的空间可能都申请不到;
图示:

在这里插入图片描述

2)复制算法: 解决了内存碎片问题;
复制算法过程:把整个内存空间分成两段(为了好描述过程,这里把内存空间分为a,b,a与b一样),一次只使用一半;如果使用a内存,将a内存中不是垃圾对象的拷贝到没有使用的另一边b内存中,然后再统一释放内存;
图示复制算法:

在这里插入图片描述
缺点:1)内存利用率比较低;
2)如果当前只要少部分垃圾,大部分对象需要保留,就需要花费高的复制成本;

3)标记整理
标记整理思想:结合上述标记清除,标记整理在其上在加上一个从后向前搬运元素的过程;
标记整理图示:

在这里插入图片描述
特点:1)解决了内存碎片的问题
2)但从后向前搬运的开销比较大;

5.3 JVM的分代回收机制

分代回收机制:综合上述思想,针对不同的情况,使用不同的策略对垃圾进行回收;
分代回收图示:

在这里插入图片描述

分代回收过程:
1)·新创建的对象存放到伊甸区;
2)伊甸区的对象,经过第一轮GC,会通过复制算法,拷贝到生存区;生存区分为两半,大小相等,每次只使用一半;
在生存区中是垃圾对象就淘汰,不是垃圾对象就复制到另一半,一直重复上述过程;
3)对象在生存区,经过若干轮GC,年龄增长到 一定程度,就会通过复制算法拷贝到老年代区;
4)进入老年代的对象,年龄比较大,针对老年代的GC扫描频次会降低,消亡率就降低了;
老年代某个对象是垃圾对象了,进行标记整理法清除;
5)特殊情况:对象非常大,直接进入老年代区;原因是大对象进行复制算法成本高,其次大对象也不多;


总结

✨✨✨各位读友,本篇分享到内容如果对你有帮助给个👍赞鼓励一下吧!!
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/27161.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最小二乘拟合平面——拉格朗日乘子法

目录 一、算法原理二、代码实现1、python2、matlab 三、算法效果 一、算法原理 设拟合出的平面方程为: a x b y c z d 0 (1) axbyczd0\tag{1} axbyczd0(1) 约束条件为: a 2 b 2 c 2 1 (2) a^2b^2c^21\tag{2} a2b2c21(2)   可以得到平面参数 a…

【Django学习】(十四)自定义action_router

之前我们的视图类可以继承GenericViewSet或者ModelViewSet,我们不用再自定义通用的action方法,但是有时候我们需要自定义action,我们该如何设计呢? 自定义action 1、手写视图逻辑 1.1、先在视图集里自定义action方法&#xff0…

4、深入理解ribbon

一、负载均衡的两种方式 服务器端负载均衡 传统的方式前端发送请求会到我们的的nginx上去,nginx作为反向代理,然后路由给后端的服务器,由于负载均衡算法是nginx提供的,而nginx是部署到服务器端的,所以这种方式又被称为…

ETLBox for .Net Crack

ETLBox for .Net Crack 为设计的轻量级ETL(提取转换负载)工具箱和数据集成库。NET。 ETL是现代商业智能应用程序的基础,是将分析与之前的所有其他组件分离的唯一方法。ETL是提取-加载、转换和转换的缩写,描述了一个由三个步骤组成的过程: 提取…

【Unity面试篇】Unity 面试题总结甄选 |热更新与Lua语言 | ❤️持续更新❤️

前言 关于Unity面试题相关的所有知识点:🐱‍🏍2023年Unity面试题大全,共十万字面试题总结【收藏一篇足够面试,持续更新】为了方便大家可以重点复习某个模块,所以将各方面的知识点进行了拆分并更新整理了新…

javascript中过滤二维对象数组重复的字段并只保留唯一值(array.filter与Array.from)

javascript中过滤二维对象数组重复的字段并只保留唯一值 1.Array.filter过滤array.filter()方法 2.Array.from过滤Array.from方法 1.Array.filter过滤 在JavaScript中,你可以使用Array.filter()和Set数据结构来过滤二维对象数组中重复的字段,只保留唯一…

Java日期类

日期类 第一代日期类: 1、Date:精确到毫秒,代表特定的瞬间 2、SimpleDateFormat: **格式化和解析日期的具体类,**它允许进行:格式化(日期 → 文本) 解析(文本 → 日期) 和 规范化。 3、常用的使用方法…

SpringBoot源码分析(6)--SpringBootExceptionReporter/异常报告器

文章目录 一、前言二、异常报告器介绍2.1、作用2.2、接口定义2.3、FailureAnalyzer错误分析器2.4、FailureAnalysisReporter错误报告器 三 、SpringBootExceptionReporter源码分析四、shutdownHook介绍4.1、背景4.2、什么是Shutdown Hook4.3、什么时候会调用Shutdown Hook4.4、…

NUXT3学习笔记2

1、配置Ant design Vue (两个安装方式随便选一种,yarn会安装的更快) npm i ant-design-vue --save yarn add ant-design-vue 2、使⽤的 Vite,你可以使⽤ unplugin-vue-components 来进⾏按需加载。 yarn add unplugin-vue-components --save 在nuxt.…

第一阶段-第十一章 Python基础的综合案例(数据可视化-地图可视化)

目录 一、基础地图使用  1.学习目标  2.视觉映射器  3.本节的演示二、疫情地图-国内疫情地图  1.案例效果  2.函数的语法  3.本节的代码演示三、疫情地图-省级疫情地图  1.案例效果  2.本节的代码演示 说明:该文章是学习 黑马程序员在B站上分享的视…

【c++修行之路】IO流架构及使用

文章目录 前言输入输出库文件读写序列化与反序列化结语 前言 大家好久不见,今天一起来学习c中的IO流。 输入输出库 这两张架构图略显复杂,这里给出一张比较清楚的IO流架构图: 也就是说,我们平时使用的诸如cin、cout、cerr、cl…

python selenium.webdriver 爬取政策文件

文章目录 获取文章链接批量爬取政策文件应用selenium爬取文件信息数据处理导出为excel 获取文章链接 获取中央人民政府网站链接,进入国务院政策文件库,分为国务院文件和部门文件(发改委、工信部、交通运输部、市场监督局、商务部等&#xff…