了解 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.mzph.cn/news/372.shtml

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

相关文章

Kerberos协议详解

0x01 kerberos协议的角色组成 Kerberos协议中存在三个角色: 客户端(Client):发送请求的一方 服务端(Server):接收请求的一方 密钥分发中心(Key distribution KDC) 密钥分发中心分为两个部分: AS(Authentication Server)&…

Nacos (2.0版本之后)状态异常集群节点状态异常

在nacos 2.0 之后正常部署后节点状态仅有一个正常,其余均为DOWN 或者SUSPICIOUS 状态 查看日志后发现 ERROR Server check fail, please check server 192.168.172.104 ,port 9849 is available , error {} 其实是nacos 相互之间不能正常通信造成的,nacos客户端升级为2.x版…

apple pencil一代的平替有哪些品牌?苹果平板的触控笔

随着苹果Pencil系列的推出,平替电容笔在国内市场得到了较好的发展,随之的销量,也开始暴涨,苹果pencil因为价格太高,导致很多人买不起。目前市场上,有不少的平替电容笔,可以替代苹果的Pencil&…

MySQL 主从复制与读写分离

MySQL 主从复制与读写分离 一、mysql读写分离的概念1、什么是读写分离?2、为什么要读写分离呢?3、什么时候要读写分离?4、主从复制与读写分离5、mysql支持的复制类型 二、主从复制的工作过程三、MySQL 读写分离原理常见的 MySQL 读写分离分为…

【Distributed】分布式ELK日志文件分析系统(二)

文章目录 一、FilebeatELK 部署1. 环境部署2. 在 Filebeat 节点上操作2.1 安装 Filebeat2.2 设置 filebeat 的主配置文件 3. 在 Apache 节点上操作3.1 在 Logstash 组件所在节点上新建一个 Logstash 配置文件 3. 启动3.1 在Logstash 组件所在节点启动3.2 在 Filebeat 节点 启动…

Stable Diffusion 用2D图片制作3D动态壁纸

如果想让我们的2D图片动起来可以使用stable-diffusion-webui-depthmap-script插件在SD中进行加工让图片动起来。 这是一个可以从单个图像创建深度图,现在也可以生成3D立体图像对的插件,无论是并排还是浮雕。生成的结果可在3D或全息设备(如VR耳机或Looking Glass显示器)上查…

大模型加速学科升级,飞桨赋能北邮“X+大模型”特色小学期

在人工智能时代,设计师与产品经理比以往更加需要关注一个事实:那就是如何利用人工智能和数据分析技术,打造让用户心动的信息交互产品和用户体验,释放人-机协同共创的巨大潜能,是决定设计产能和竞争力的关键。 在产业的…

RabbitMQ ---- 消息队列

RabbitMQ ---- 消息队列 1. MQ 的相关概念1.1 什么是 MQ1.2 为什么要用 MQ1.3 MQ 的分类1.4 MQ 的选择 2. RabbitMQ2.1 RabbitMQ 的概念2.2 四大核心概念2.3 RabbitMQ 核心部分2.4 各个名词介绍2.5 安装 1. MQ 的相关概念 1.1 什么是 MQ MQ(message queue),从字面…

爬虫之Scrapy

一 介绍 Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速、简单、可扩展的方式从网站中提取所需的数据。但目前Scrapy的用途十分广泛,可用于如数据挖掘、监测和自动化测试等领域&#x…

什么是Docker

容器技术和虚拟机 虚拟机 和一个单纯的应用程序相比,操作系统是一个很重的程序,刚装好的系统还什么都没有部署,单纯的操作系统其磁盘占用至少几十G起步,内存要几个G起步。 在这台机器上开启三个虚拟机,每个虚拟机上…

PSI算法经典论文算法概述

文章目录 什么是隐私求交PSIPSI协议分类PSI算法的分类基于哈希函数的PSI算法基于不经意传输(OT)的 PSI算法基于GC的PSI算法基于公钥加密的PSI算法基于DH的PSI算法基于RSA盲签名的PSI算法基于同态加密的PSI算法 基于差分隐私的PSI算法 总结参考文献 什么是…

为了实现上网自由,我做了一个多功能串口服务器

项目作者:小华的物联网嵌入式之旅 介绍:从事电气自动化行业,多次获得物联网设计竞赛,爱好嵌入式设计开发,物联网开发。 设计方案思路的由来,是因为我们现在的开发板基本需要通过串口与WIFI模组或以太网模…

[Linux] 最基础简单的线程池 及其 单例模式的实现

本篇文章主要用到线程相关内容, 下面是博主关于线程相关内容的文章: [Linux] 线程同步分析:什么是条件变量?生产者消费者模型是什么?POSIX信号量怎么用?阻塞队列和环形队列模拟生产者消费者模型 [Linux] 线程互斥分析: 多线程的问…

华为、阿里巴巴、字节跳动 100+ Python 面试问题总结(一)

系列文章目录 个人简介:机电专业在读研究生,CSDN内容合伙人,博主个人首页 Python面试专栏:《Python面试》此专栏面向准备面试的2024届毕业生。欢迎阅读,一起进步!🌟🌟🌟 …

华为发布大模型时代AI存储新品

7月14日,华为发布大模型时代AI存储新品,为基础模型训练、行业模型训练,细分场景模型训练推理提供存储最优解,释放AI新动能。 企业在开发及实施大模型应用过程中,面临四大挑战: 首先,数据准备时…

剑指offer刷题笔记--Num41-50

1--数据流中的中位数(41) 主要思路: 维护两个优先队列,Q1大数优先,存储比中位数小的数;Q2小数优先,存储比中位数大的数; 当存储的数为偶数时,Q1.size() Q2.size(), 中位…

解决github无法拉取submodule子模块的问题

引言 当使用git clone --recursive url 拉取一个配置了子模块的仓库后,会卡住。 同时在使用git clone 拉去https的url时,同样可能会出现一直卡在cloning int reposity...本文提供一个简单的脚本来解决该问题。 前置准备 需要配置好git的相关配置&…

快速配置 Rust 开发环境并编写一个小应用

安装: curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh 更新: Rust 的升级非常频繁. 如果安装 Rustup 后已有一段时间,那么很可能 Rust 版本已经过时, 运行 rustup update 获取最新版本的 Rust rustc:编译Rust程序 rustc只适合简单的Rust程序&#xf…

qt和vue的交互

1、首先在vue项目中引入qwebchannel /******************************************************************************** Copyright (C) 2016 The Qt Company Ltd.** Copyright (C) 2016 Klarlvdalens Datakonsult AB, a KDAB Group company, infokdab.com, author Milian …

记录--再也不用手动改package.json的版本号

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 本文的起因是有在代码仓库发包后,同事问我“为什么package.json 里的版本还是原来的,有没有更新?”,这个时候我意识到,我们完全没有必要在每…