JVM常见知识点

在《深入理解Java虚拟机》一书中,介绍了JVM的相关特性。

1、JVM的内存区域划分

在真实的操作系统中,对于地址空间进行了分区域的设计,由于JVM是仿照真实的机器进行设计的,那么也进行了分区域的设计。核心区域有四个,分别为程序计数器、元数据区、栈、堆。此处的栈和堆与数据结构中的栈和堆不一样。

元数据区和堆,是整个 java 进程共用一份的,程序计数器和栈,在一个进程中可能有多份,即每个进程都有一份。

1)程序计数器

很小的一块地址,用来记录指令运行到哪个地址了。

2)元数据区

保存当前类被加载好的数据。

.java 文件需要先被编译为 .class 文件,再将 .class 文件加载到内存中。

元数据区保存类的名字、类的可见性、类的继承关系、实现的接口等。

元数据区通常保存静态成员变量。

3)栈

保存方法的调用关系,此处使用了数据结构中的栈来进行保存。将先执行到的方法先入栈,后执行方法后入栈。

比如,在 main 方法中有 test 方法,当开始运行时,就会先将 main 入栈,当代码执行到 test 方法后,就会将 test 方法入栈,当test 方法运行结束后,就会返回到 main 中继续往下执行。图示如下:

栈中的每个方格就是一个栈帧,栈帧中保存了该方法的参数、局部变量、返回值、返回的地址(即该方法结束后应该返回到哪个方法继续执行)。

栈空间通常只有几MB、几十MB。

当程序出现异常(如递归代码有问题)时,有可能会出现栈溢出(StackOverFlow)的情况。

栈通常保存局部变量。

4)堆

堆是 JVM 中最大的内存空间。用来保存 new 出来的对象的。

2、类加载机制

1)类加载的步骤

类加载一共有三大阶段,第二阶段又分为三个步骤。

① 加载,找到 .class 文件

根据类的全限定名(包名 + 类名,如 java.lang.String)找到后打开文件,将文件内容读取到内u村中;

②验证

校验 .class 文件中的内容是否合法,并将文件中的内容转化为结构化的数据;

③准备

给类对象申请内存空间,即全 0 的空间;

④解析

针对字符串常量进行初始化。将文件中的字符串常量放到元数据区中。

⑤初始化

针对类对象进行最终的初始化,包括针对类对象各种属性的填充和类的静态成员。

若该类的父类还没有加载,此环节也会触发父类的加载。

上面的五步中,2、3、4步为第二阶段。

2)双亲委派模型

在类加载的第一步中,需要根据类的全限定名找到 .class 文件,这就涉及到双亲委派模型。

在进行类加载时,需要使用到类加载器。JVM 默认提供三种类加载器,分别为 BootstrapClassLoader(Java 标准库目录)、ExtensionClassLoader(Java 拓展库目录)、ApplicationClassLoader(Java 第三方库 / 当前项目)。BootstrapClassLoader 是 ExtensionClassLoader 的父类,ExtensionClassLoader 是 ApplicationClassLoader 的父类。此处的父类不是父子关系,而是通过 prant 引用进行指向。

在进行类加载时,将 ApplicationClassLoader 作为入口开始,把“类加载”的任务交给 ExtensionClassLoader 去完成,但 ExtensionClassLoader 也不会马上进行查找,而是将“类加载”的任务交给 BootstrapClassLoader 去完成。然后 BootstrapClassLoader 就会在标准库范围进行查找该 .class 文件是否存在,若存在,就加载,若不存在,就把任务返回给 ExtensionClassLoader ,在拓展库中进行查找,若找到就加载,若没有找到就将任务返回给 ApplicationClassLoader,在第三方库 / 当前项目进行查找,若找到就加载,若没找到,就会抛出 ClassNotFoundException 异常。流程图如下:

3、垃圾回收器 (GC)

由于手动进行内存释放太麻烦,并且如果忘记释放就会出现内存泄漏,于是,Java使用 GC 来进行垃圾回收。这里指的垃圾通常为对象,若这个对象在之后的代码中不会用到,就会被视为“垃圾”,进而被释放内存。

垃圾回收器回收的是堆上的内存。

使用 GC 释放垃圾分为以下两步:找到垃圾、释放垃圾。

1)找到垃圾

找到垃圾即找到不使用的类对象。有下面两个方法:

①引用计数(Python等语言使用)

在每次创建对象时,都使用一块小的内存空间来保存一个整数,这个整数就是当前对象有都少个引用指向它。每次进行引用赋值时,都会触发这个整数的修改。若整数变为0,就说明没有引用指向这个对象,即这个对象变成了垃圾。

但是这个方法也有缺陷,即:

内存消耗更多,当对象本身较小时,消耗的空间比例就更大;

可能会出现“循环引用”的问题。(需要搭配其他的方案来解决该问题)。

可达性分析(Java使用)

由于引用计数需要消耗空间,于是可达性分析就用时间来换空间。

以代码中的一些特定对象作为起点,对其他对象进行遍历,将每次遍历到的对象设为可达,遍历完成后,不可达的对象就是已经没有引用指向的对象,即垃圾,需要被回收掉。

这里的遍历很像数或图的遍历。现有下面的二叉树:

这里的每一个结点都代表一个对象。当将 c.right = null 时,在从 a 开始遍历时,f 结点就遍历不到,这时 f 就是不可达的,就会将 f 回收掉;当将 a.right = null 时 ,当从 a 开始遍历时,c 结点就是不可达的,也就导致 f 结点不可达,就会将 c 和 f 回收掉。

缺点:每次需要将所有对象遍历一遍,需要配消耗较大的时间和资源。

2)释放垃圾

①标记-清除

把垃圾对象的内存直接释放,但是这样做会产生内存碎片问题。

图中b、d、f、h是垃圾,若将其直接释放,就会导致释放后的内存空间是零散的,但由于申请内存时需要连续的内存,那么这些被释放的内存空间就会无法使用(需要的申请内存大于碎片的内存),导致内存申请失败。

②复制算法

在使用一部分内存时,每次只使用这一部分的一半内存,将创建的对象放在这一半内存上,若有的对象需要被回收,就会将不是垃圾的对象复制到另一半内存上,再将原来那一部分的对象直接回收。

这种做法就避免了产生碎片内存的问题。但也有缺点:

空间利用率低;

一旦不是垃圾的对象较多或需要复制的对象较大,就会提高复制成本,降低程序运行的效率。

③标记-整理

如上图,现b、d、f、h都是垃圾对象,于是就会将其他不是垃圾的对象向前移,移动后的结果如下图:

 之后就会将e、f、g、h直接释放。

这样做即避免出现内存碎片问题,又保证了内存的利用率。但是依然会涉及到对象的复制,若对象较多或较大,就会提高复制成本。

④将上面的三种方法结合起来

使用“代”来表示对象的年龄,即每一次遍历后若不是垃圾就加1,初始为0。

GC将内存区域划分为若干个区域,有新生代区、老年代区,新生代区中又包含伊甸区、幸存区。

伊甸区有幸存区的空间比例通常为8:1:1。

针对不同年龄的对象使用的测率不同。

若为新生代对象,就放到伊甸区中,由于绝大部分新生代对象都会在第一轮GC中变为垃圾对象,于是幸存区就比伊甸区小。 在进行遍历时,若新生代对象不是垃圾,就会放到幸存区,,若是垃圾就会直接释放。由于需要复制的对象较少,就使得复制的开销相对较小。

幸存区中的对象也需要进行遍历,若有的对象时垃圾,就会将不是垃圾的对象复制到另一个幸存区中,再将幸存区中的对象全部释放。

若某个对象经过多轮的遍历有都还是有用的,这时就会将该对象放到老年代中。由于老年代对象的生命周期较长,就使得整理的开销也较小。

于是每个对象都会经历以下几个时期:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电脑系统bcd文件损坏修复方法:小白也会的修复方法

电脑系统bcd文件损坏怎么办?当电脑开机时出现bcd文件损坏,一般情况是由于电脑系统的引导坏了,需要进行修复。现在越来越多的小伙伴遇到电脑引导丢失或者安装后无法正常引导的问题,我们现在一般是pe下进行修复引导,那么电脑系统bc…

Flutter_学习记录_导航和其他

Flutter 的导航页面跳转,是通过组件Navigator 和 组件MaterialPageRoute来实现的,Navigator提供了很多个方法,但是目前,我只记录我学习过程中接触到的方法: Navigator.push(), 跳转下一个页面Navigator.pop(), 返回上一…

【架构面试】二、消息队列和MySQL和Redis

MQ MQ消息中间件 问题引出与MQ作用 常见面试问题:面试官常针对项目中使用MQ技术的候选人提问,如如何确保消息不丢失,该问题可考察候选人技术能力。MQ应用场景及作用:以京东系统下单扣减京豆为例,MQ用于交易服和京豆服…

Git 如何将旧仓库迁移新仓库中,但不显示旧的提交记录

一、异常错误 场景:我想把旧仓库迁移新仓库中,放进去之后,新仓库会显示这个项目之前的所有提交,如何不显示这些旧的提交? 二、原因 我们需要将旧仓库迁移新仓库中,但是又不想在新仓库中显示旧的提交记录…

02-AD-绘制原理图(画示意图+添加已有P封装)

画示意图添加已有P封装 画原理示意图绘制原理图:电容绘制原理图:晶体绘制发光二极管绘制TVS二极管绘制按键绘制拨码开关绘制双排针绘制单排针绘制TYPE母座画图技巧:按顺序递增,删除不用的先画线,再画框 绘制AMS芯片填充框透明显示:防止遮挡其他部分不需要添加其他内容 绘制STM3…

C++红黑树详解

文章目录 红黑树概念规则为什么最长路径不超过最短路径的二倍?红黑树的时间复杂度红黑树的结构插入叔叔节点情况的讨论只变色(叔叔存在且为红)抽象的情况变色单旋(叔叔不存在或叔叔存在且为黑)变色双旋(叔叔不存在或叔叔存在且为黑…

LLaMA-Factory 微调LLaMA3

LLaMA-Factory 框架 首先需要通过vscode连接远程服务器哦 如果是租赁的AutoDL服务器,一定要将模型下载到数据盘。 git clone https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory pip install -e . 准备训练数据 训练数据: fintech.json …

FFmpeg 头文件完美翻译之 libavcodec 模块

前言 众所周知,FFmpeg 的代码开发上手难度较高,源于官方提供的文档很少有包含代码教程相关的。要想熟练掌握 FFmpeg 的代码库开发,需要借助它的头文件,FFmpeg 把很多代码库教程都写在头文件里面。因此,熟读头文件的内…

IDEA工具下载、配置和Tomcat配置

1. IDEA工具下载、配置 1.1. IDEA工具下载 1.1.1. 下载方式一 官方地址下载 1.1.2. 下载方式二 官方地址下载:https://www.jetbrains.com/idea/ 1.1.3. 注册账户 官网地址:https://account.jetbrains.com/login 1.1.4. JetBrains官方账号注册…

AMQP是什么

文章目录 AMQP是什么一、引言二、AMQP的核心概念1、协议定义2、消息传递模型 三、AMQP的工作原理1、消息路由机制2、消息确认机制 四、使用示例1、Java代码示例1.1、项目依赖1.2、配置文件1.3、消息配置1.4、消息生产者1.5、消息消费者 五、总结 AMQP是什么 一、引言 在现代分…

ESP32基于ESPIDF I2C设备探测和使用

ESP32基于ESPIDF I2C设备探测和使用 📍I2C接口介绍和参考:https://docs.espressif.com/projects/esp-idf/zh_CN/stable/esp32/api-reference/peripherals/i2c.html 📓I2C 主机探测 主要主要利用 i2c_master_probe() 函数,来检测…

计算机网络 (58)无线局域网WLAN

前言 无线局域网WLAN(Wireless Local Area Network)是一种利用无线通信技术将计算机设备互联起来,构成可以互相通信和实现资源共享的网络体系。 一、定义与特点 定义: WLAN通过无线信道代替有线传输介质连接两个或多个设备形成一个…

物业管理平台系统提升社区智能化服务效率与管理水平

内容概要 在现代社会中,物业管理平台系统的出现,为社区的智能化服务带来了革命性的变化。这种系统不仅仅是提升了工作效率,更是通过一系列智能化功能,根本性改变了物业管理的方式。比如,在广告位管理方面,…

基于SpringBoot的网上考试系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…

【C++】类与对象初级应用篇:打造自定义日期类与日期计算器(2w5k字长文附源码)

文章目录 一、日期类的实现1. 日期类的默认成员函数的分析与实现构造函数其它默认成员函数 2. 各种逻辑比较运算符重载3. 日期加与减天数日期加天数系列日期减天数系列日期加减天数的最后修定和- -系列 4. 日期减日期方法一方法二 5. 流插入与流提取重载流插入重载流提取重载(含…

51单片机入门_01_单片机(MCU)概述(使用STC89C52芯片)

文章目录 1. 什么是单片机1.1 微型计算机的组成1.2 微型计算机的应用形态1.3 单板微型计算机1.4 单片机(MCU)1.4.1 单片机内部结构1.4.2 单片机应用系统的组成 1.5 80C51单片机系列1.5.1 STC公司的51单片机1.5.1 STC公司单片机的命名规则 2. 单片机的特点及应用领域2.1 单片机的…

“腾讯、钉钉、飞书” 会议开源平替,免费功能强大

在数字化时代,远程办公和线上协作越来越火。然而,市面上的视频会议工具要么贵得离谱,要么功能受限,甚至还有些在数据安全和隐私保护上让人不放心。 今天开源君给大家安利一个超棒的开源项目 - Jitsi Meet,这可是我在网…

【软件设计师中级】-笔记缩减版本-计算机系统基础知识

1. 计算机系统基础知识 1.1. 计算机系统硬件基本组成硬件 中央处理器(CPU)硬件系统的核心 运算器 控制器 存储器(记忆设备) 内部存储器(速度高,容量小):临时存放程序、数据及中间结…

【Linux】命令为桥,存在为岸,穿越虚拟世界的哲学之道

文章目录 Linux基础入门:探索操作系统的内核与命令一、Linux背景与发展历史1.1 Linux的起源与发展1.2 Linux与Windows的对比 二、Linux的常用命令2.1 ls命令 - "List"(列出文件)2.2 pwd命令 - "Print Working Directory"&#xff08…

Pyecharts之散点图的视觉扩展

在数据可视化中,散点图是一种强大的工具,可用于展示数据点在二维平面上的分布情况。通过添加各种视觉组件,我们可以让散点图变得更加丰富和具有表现力,更能反映数据的多维度特征。本文将详细解读如何为散点图添加不同的视觉组件&a…