JVM基础-Hotspot VM相关知识学习

news2024/12/24 3:34:48

这里写目录标题

    • jdk
    • JVM虚拟机
      • 类的生命周期
      • 类加载的时机
      • 类的双亲委派机制
      • 类的验证
    • java对象
          • Mark Word
          • Klass Pointer
          • 实例数据
          • 对齐数据
    • 字符串常量池
    • 垃圾收集器
      • 1.Serial收集器(串行收集器)
      • cms垃圾算法
      • G1垃圾收集器
          • 与CMS收集器相比, G1收集器的优势:
          • G1收集器的实现原理:

JVM参考文章:

JVM之 方法区、永久代(PermGen space)、元空间(Metaspace)三者的区别

jdk

JRE是java运行时环境而JDK是java开发工具包,JDK包含JRE,但是JRE可以独立安装。

  • JDK:java development kit (java开发工具),JDK 是用于开发 Java 程序的最小环境。

  • JRE:java runtime environment (java运行时环境),是提供给 Java 程序运行的最小环境。

JRE包含了java虚拟机、java基础类库。是使用java语言编写的程序运行所需要的软件环境,是提供给想运行java程序的用户使用的。JDK是程序员使用java语言编写java程序所需的开发工具包,是提供给程序员使用的。运行java程序只需安装JRE。如果需要编写java程序,需要安装JDK。

在这里插入图片描述

JVM虚拟机

在这里插入图片描述

  • 内存模型中线程独享的有:线程栈(虚拟机栈)、本地方法栈、程序计数器
  • 内存模型中线程共享的有:堆、方法区(1.7以前名为永久区,1.8后为元空间)
  • 常量池中的对象在1.6以前位于用永久区,1.7以后位于
  • 线程栈的最小单元叫栈帧,组成部分有局部变量表、操作数栈、动态链接、方法出口

在这里插入图片描述

  • 在方法区里面有一个运行常量池,包含变量和方法,class文件所有的变量和引用作为符号引用,保存在class文件的常量池中。

  • 描述一个方法调用了其他的方法的时候就是通过常量池中指向方法的符号引用来表示。那么动态连接的作用就是将这些符号引用转化成调用方法的直接引用

  • 所以动态链接:将对方法的符号引用 链接成 对调用方法的直接引用

  • 动态链接(虚方法)发生在运行时,静态链接发生在编译时(private\static\final)

  • 重载是静态绑定,重写是动态绑定

JVM知识梳理之二_JVM的常量池

在这里插入图片描述

类的生命周期

在这里插入图片描述

类加载的时机

下面5种情况下会导致类初始化,因此必须在发生这5种情况之前对类进行加载。

  • 当虚拟机启动时加载主类。
  • 使用 java . lang . reflect 包的方法对类进行反射调用时,如果类还没有初始化,则需要进行初始化。
  • new 一个类的对象,调用类的静态成员(除了由 final 修饰的常量外)和静态方法,无论是解析执行还是编译执行的情况下,都会在处理 new 、 getstatic 、 putstatic 或 invokestatic 字节码指令时对类进行初始化。在第9章中会介绍使用 new 字节码指令创建对象的过程,其中就会有触发类装载的逻辑判断。
  • 当初始化一个类时,如果其父类没有被初始化,则先初始化其父类。后续在介绍函数 InstanceKlass :: initialize _ impl ()时会看到这个判断逻辑。
  • 使用JDK7的动态语言支持时,如果一个 java . lang . invoke . MethodHandle 对象最后的解析结果是 REF _ getStatic 、 REF _ putStatic 和 REF _ invokeStatic 的方法句柄,并且这个方法句柄所对应的类没有进行初始化,则需要先进行初始化。

可以通过调用 ClassLoader 类的 loadClass ()方法装载类,还可以调用 java . lang . Class .
forName ()方法通过反射的方式完成装载类。 loadClass ()方法只是将 Class 文件装载到 HotSpot VM 中,而 forName ()方法会完成类的装载、链接和初始化过程。

类的双亲委派机制

各个类加载器之间并不是继承关系,而是表示工作过程,具体说就是,对于一个加载类的具体请求,首先要委派给自己的父类加载器去加载,只有父类加载器无法完成加载请求时子类加载器才会尝试加载,这就叫"双亲委派"。
在这里插入图片描述

在这里插入图片描述

类的验证

类在连接过程中会涉及验证。 HotSpot VM 会遵守 Java 虚拟机的规范,对 Class 文件中包含的信息进行合法性验证,以保证 HotSpot VM 的安全。从整体上看,大致进行如下4方面的验证。

  • 文件格式验证:包括魔数和版本号等;
  • 元数据验证:对程序进行语义分析,如是否有父类,是否继承了不被继承的类,是否实现了父类或者接口中所有要求实现的方法;
  • 字节码验证:指令级别的语义验证,如跳转指令不会跳转到方法体以外的代码上;.
  • 符号引用验证:符号引用转化为直接引用的时候,可以看作对类自身以外的信息进行匹配验证,如通过全限定名是否能找到对应的类等。

在这里插入图片描述
在这里插入图片描述

全网最硬核 JVM TLAB(Thread Local Allocate Buffer) 分析

java对象

在这里插入图片描述
在这里插入图片描述

Mark Word

32位Mark Word:
在这里插入图片描述

64位Mark Word:
在这里插入图片描述

  • 锁标志位(lock):区分锁状态,11时表示对象待GC回收状态, 只有最后2位锁标识(11)有效。
  • biased_lock:是否偏向锁,由于正常锁和偏向锁的锁标识都是 01,没办法区分,这里引入一位的偏向锁标识位。
  • 分代年龄(age):表示对象被GC的次数,当该次数到达阈值(最大为15,默认为15,CMS垃圾收集器默认为6)的时候,对象就会转移到老年代。
  • 对象的hashcode(hash):运行期间调用System.identityHashCode()来计算,延迟计算,并把结果赋值到这里。当对象加锁后,计算的结果31位不够表示,在偏向锁,轻量锁,重量锁,hashcode会被转移到Monitor中。
  • 偏向锁的线程ID(JavaThread):偏向模式的时候,当某个线程持有对象的时候,对象这里就会被置为该线程的ID。 在后面的操作中,就无需再进行尝试获取锁的动作。
  • epoch:偏向锁在CAS锁操作过程中,偏向性标识,表示对象更偏向哪个锁。
  • ptr_to_lock_record:轻量级锁状态下,指向栈中锁记录的指针。当锁获取是无竞争的时,JVM使用原子操作而不是OS互斥。这种技术称为轻量级锁定。在轻量级锁定的情况下,JVM通过CAS操作在对象的标题字中设置指向锁记录的指针。
  • ptr_to_heavyweight_monitor:重量级锁状态下,指向对象监视器Monitor的指针。如果两个不同的线程同时在同一个对象上竞争,则必须将轻量级锁定升级到Monitor以管理等待的线程。在重量级锁定的情况下,JVM在对象的ptr_to_heavyweight_monitor设置指向Monitor的指针。
Klass Pointer

即类型指针,是对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。

实例数据

如果对象有属性字段,则这里会有数据信息。如果对象无属性字段,则这里就不会有数据。根据字段类型的不同占不同的字节,例如boolean类型占1个字节,int类型占4个字节等等;

对齐数据

对象可以有对齐数据也可以没有。默认情况下,Java虚拟机堆中对象的起始地址需要对齐至8的倍数。如果一个对象用不到8N个字节则需要对其填充,以此来补齐对象头和实例数据占用内存之后剩余的空间大小。如果对象头和实例数据已经占满了JVM所分配的内存空间,那么就不用再进行对齐填充了。
所有的对象分配的字节总SIZE需要是8的倍数,如果前面的对象头和实例数据占用的总SIZE不满足要求,则通过对齐数据来填满。

为什么要对齐数据?
字段内存对齐的其中一个原因,是让字段只出现在同一CPU的缓存行中。如果字段不是对齐的,那么就有可能出现跨缓存行的字段。也就是说,该字段的读取可能需要替换两个缓存行,而该字段的存储也会同时污染两个缓存行。这两种情况对程序的执行效率而言都是不利的。其实对其填充的最终目的是为了计算机高效寻址。

在这里插入图片描述
默认情况下JVM开启了指针压缩,对象A大小情况

  • 【Mark word】为8字节
  • 【Klass Pointer】被压缩为4字节
  • 实例数据:int类型id大小为4字节、String类型name大小为4字节、byte类型b大小为1字节,byte类型对象内对齐3字节、Object类型o大小为4字节
  • 对齐填充:综上数据大小为28字节,数据对齐添加4字节,对象A的实际大小为32字节

new Object() 生成的对象大小为16个字节

在这里插入图片描述
手动关闭JVM指针压缩,对象A大小情况

  • 【Mark word】为8字节
  • 【Klass Pointer】为8字节
  • 实例数据:int类型id大小为4字节、String类型name大小为8字节、byte类型b大小为1字节,byte类型对象内对齐3字节、Object类型o大小为8字节
  • 对齐填充:综上数据大小为40字节,数据对齐不用补齐,对象A的实际大小为40字节

Java对象中实例数据发生的间隙填充alignment/padding gap条件是什么?

字符串常量池

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

垃圾收集器

在这里插入图片描述
在这里插入图片描述

图中的连线表示可以使用连线两端的两种收集器分别收集年轻代和老年代的内存空间,而G1收集器既以收集年轻代的内存空间,也可以收集老年代的内存空间。

1.Serial收集器(串行收集器)

Serial 收集器是一个单线程的收集器,采用"复制"算法。单线程的意义一方面指它
只会使用一个 CPU 或一条收集线程去完成圾收集工作,另一方面指在进行垃圾收集时必须暂停其他的工作线程,直到收集结束。
Serial 收集器的工作过程如图所示。
在这里插入图片描述

Serial 收集器是一个单线程的收集器,采用"复制"算法。"单线程"并不是说只使
用一个 CPU 或一条收集线程去完成垃圾收集工作,而是指在进行垃圾收集时,必须暂停其他的工作线程,直到收集结束。本章将详细介绍 Serial 垃圾回收的具体实现过程。

cms垃圾算法

在这里插入图片描述

G1垃圾收集器

在这里插入图片描述

在这里插入图片描述

与CMS收集器相比, G1收集器的优势:
  • 基于标记-整理算法, 不会产生大量的内存碎片;
  • 可以更加精确地控制停顿时间, 在不牺牲吞吐量前提下, 实现低停顿垃圾回收.
G1收集器的实现原理:
  • G1收集器能够避免全区域的垃圾收集, 它把堆内存划分为大小固定的几个独立区域, 并跟踪这些区域的垃圾收集进度, 同时在后台维护一个优先级列表, 每次根据所允许的收集时间, 优先回收垃圾最多的区域

在这里插入图片描述

关于垃圾收集器G1与ZGC

在这里插入图片描述

  • 默认情况下年轻代所占内存为堆空间的1/3,其中Eden区大小占年轻代空间的80%,s0和S1各占10%; 永久代所占内存为堆空间的2/3

在这里插入图片描述

STW的原因?
防止少标或多标(多标产生浮动垃圾

在这里插入图片描述
1.长期存活的对象进入老年代

幸存区复制一次,则年龄增加1。当对象的年龄达到设定的阈值时,将会晋升到老年代。默认情况下,并行 GC 的年龄阈值为15,并发 GC 的年龄阈值为6。由于 age 只有4位,所以最大值为15,这就是﹣ XX : MaxTenuring Threshold 选项最大值为15的原因。

虚拟机给每个对象定义了一个对象年龄计数器。如果对象在 Eden 空间分配并经过第
一次 YGC 后仍然存活,在将对象移动到 To Survivor 空间后对象年龄会设置为1。对象在 Survivor 空间每熬过一次, YGC 年龄就加一岁,当它的年龄增加到一定程度(默认为15岁)时,就会晋升到老年代中。对象晋升老年代的年龄阈值,可以通过﹣ XX : MaxTenuring - Threshold 选项来设置。 ageTable 类中定义 table _ size 数组的大小为16,由于通过﹣ XX : Max - TenuringThreshold 选项可设置的最大年龄为15,所以数组的大小需要设置为16,因为还需要通过 sizes [0]表示一次都未移动的对象,不过实际上不会统计 sizes [0],因为 sizes [0]
的值一直为0。

2.动态对象年龄判定
为了能更好地适应不同程度的内存状况,虚拟机并不总是要求对象的年龄必须达到 MaxTenuringThreshold 才能晋升到老年代。如果在 Survivor 空间中小于等于某个年龄的所有对象空间的总和大于 Survivor 空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到 MaxTenuringThreshold 中要求的年龄。因此需要通过 sizes 数组统计年轻代中各个年龄对象的总空间。

3.触发 YGC
大多数情况下,对象直接在年轻代中的 Eden 空间进行分配,如果 Eden 区域没有足够的空间,那么就会触发 YGC ( Minor GC ,年轻代垃圾回收), YGC 处理的区域只有年轻代。下面结合年轻代对象的内存分配看一下触发 YGC 的时机:

  • 新对象会先尝试在栈上分配,如果不行则尝试在 TLAB 中分配,否则再看是否满足大对象条件可以在老年代分配,最后才考虑在 Eden 区申请空间。
  • 如果 Eden 区没有合适的空间,则 HotSpot VM 在进行 YGC 之前会判断老年代最大的可用连续空间是否大于新生代的所有对象的总空间,具体判断流程如下:
    1. 如果大于的话,直接执行 YGC 。
    2. 如果小于,则判断是否开启了 HandlePromotionFailure ,如果没有开启则直接执行
      FGC .
    3. 如果开启了 HandlePromotionFailure , HotSpot VM 会判断老年代的最大连续内存空间是否大于历次晋升的平均内存空间(晋级老年代对象的平均内存空间),如果小于则直接执行 FGC ;如果大于,则执行 YGC 。

对于 HandlePromotionFailure ,我们可以这样理解,在发生 YGC之前,虚拟机会先检查老年代的最大的连续内存空间是否大于新生代的所有对象的总空间,如果这个条件成立,则 YGC是安全的。如果不成立,虚拟机会查看 HandlePromotionFailure设置值是否允许判断失败,如果允许,那么会继续检查老年代最大可用的连续内存空间是否大于历次晋级到老年代对象的平均内存空间,如果大于就尝试一次YGC ,如果小于,或者 Handle - PromotionFailure 不愿承担风险就要进行一次 FGC 。

触发 GC 的流程如图所示。
在这里插入图片描述
JVM随笔 — 安全点(safe point)与 安全区域( safe region)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

开利网络到访东家集团,沟通招商加盟数字化机制落地事项

近日,开利网络到访东家集团,就集团近日开展的奖金池激励制度的推进情况和市场反馈进行复盘与沟通。通过打破“层层中间商”,提供厂家直供价格的方式,东家集团推出了数字化激励机制,消费集团会员礼包即可在会员专区进行…

Layui快速入门之第五节 导航

目录 一:基本概念 导航依赖element模块 API 渲染 属性 事件 二:水平导航 常规用法: 三:垂直导航 四:侧边垂直导航 五:导航主题 六:加入徽章等元素 七:面包屑导航 ps&a…

大学经典题目:Java输出杨辉三角形

本节利用​ 过 Java 语 ​言中的流程控制语句,如条件语句、循环语句和跳转语句等知识输出一个指定行数的杨辉三角形。 杨辉三角形由数字进行排列,可以把它看作是一个数字表,其基本特性是两侧数值均为 1,其他位置的数值是其左上方数…

Kettle——大数据ETL工具

文章目录 ETL一、Kettle二、安装和运行Kettle三、Kettle使用四、Kettle核心概念可视化转换步骤跳 ETL ETL(Extract-Transform-Load,即数据抽取、转换、转载),对于企业或行业应用来说,我们经常会遇到各种数据的处理,转换&#xff…

【操作系统】进程的概念、组成、特征

概念组成 程序:静态的放在磁盘(外存)里的可执行文件(代码) 作业:代码+数据+申请(JCB)(外存) 进程:程序的一次执行过程。 …

5. 自动求导

5.1 向量链式法则 ① 例子1是一个线性回归的例子,如下图所示。 5.2 自动求导 5.3 计算图 5.4 两种模型 ① b是之前计算的结果,是一个已知的值。 5.5 复杂度 5.6 自动求导 import torch x torch.arange(4.0) x 结果: ② 在外面计算y关于x的…

linux 用户、组操作

一、创建用户并设置密码 #创建用户 duoergun useradd duoergun #设置用户 duoergun 密码 passwd duoergun二、创建组 #创建组 qingdynasty groupadd qingdynasty三、用户添加到组,用户从组删除 #添加用户duoergun到组qingdynasty usermod -aG qingdynasty duoer…

【CSS】React项目如何在CSS样式文件中使用变量

需求 在修改样式时候,需要根据不同条件,使用不同的样式,使用动态类需要多重判断,是否考虑使用变量传入的方式呢 应该怎么做 tsx import ./App.css; import ./test.cssfunction App() {const styles {--var: white,};return (…

20230912java面经整理

1.gc算法有哪些 引用计数(循环引用)和可达性分析找到无用的对象 标记-清除:简单,内存碎片,大对象找不到空间 标记-复制:分成两半,清理一半,没有碎片,如果存活多效率低&a…

Bigemap 在土地图利用环境生态行业中的应用

工具 Bigemap gis office地图软件 BIGEMAP GIS Office-全能版 Bigemap APP_卫星地图APP_高清卫星地图APP Bigemap 在土地图利用环境生态行业中的应用  使用场景 : 1. 土地利用占地管理: 核对数据,查看企业的实际占地是否超出宗地&…

电商运营管理——广告系统

广告位对于电商平台而言,具有非常重要的作用。如何设计一个广告位是本篇文章重点讲述的内容,作者从六个方面出发,系统地介绍该如何去搭建一个广告位,能为产品设计的同学提供一些思路。 对于电商平台,广告位无论是对产品…

制造业企业使用哪种ERP系统好?金蝶还是用友?

制造业企业使用哪种ERP系统好?金蝶还是用友? 综合来看,这几位都算是是典型的ERP软件,它有着ERP软件应该有的基础功能,并且做的也比较成熟。下面是本文对这几个软件的总结 金蝶: 优势:1.产品丰…

mysql逻辑备份和恢复

备份恢复指令 1 全备 (变量为密码、端口号、输出路径。 --compress支持压缩) mysqldump -uroot -p*** -P*** --single-transaction --master-data2 --flush-logs --hex-blob --flush-privileges --triggers --routines --events --all-databases > …

【100天精通Python】Day61:Python 数据分析_Pandas可视化功能:绘制饼图,箱线图,散点图,散点图矩阵,热力图,面积图等(示例+代码)

目录 1 Pandas 可视化功能 2 Pandas绘图实例 2.1 绘制线图 2.2 绘制柱状图 2.3 绘制随机散点图 2.4 绘制饼图 2.5 绘制箱线图A 2.6 绘制箱线图B 2.7 绘制散点图矩阵 2.8 绘制面积图 2.9 绘制热力图 2.10 绘制核密度估计图 1 Pandas 可视化功能 pandas是一个强大的数…

在 Python 中实现 DBSCAN

一、说明 DBSCAN(Density-Based Spatial Clustering of Applications with Noise)聚类是一种基于密度的聚类算法。它能够根据数据点的密度来将数据划分为不同的类别,并可以自动识别离群点。DBSCAN聚类算法的核心思想是将密度高的数据点划分为…

MacVim for Mac:强大的文本编辑器,提升你的编程体验

在Mac上,有这样一款独特的文本编辑器——MacVim for Mac,它以其强大的功能和出色的性能,吸引了广大的程序员和编程爱好者。这款编辑器不仅继承了Unix编辑器Vi的强大功能,更通过创新的设计和功能拓展,提供了一款更完整、…

批量上传文件,以input上传文件,后端以List<MultipartFile>类型接收

批量上传文件,以input上传文件,后端以List类型接收 一、后端接口二、前端对接三、测试 最近公司要求要做一个批量上传文件的功能,以往做的导入Excel表格、上传图片都是上传一个文件的,此次在开发的过程中着实让我犯了难&#xff0…

vue Echarts饼图指定颜色与数据对应

需求:一般自定义颜色是按照数据的顺序依次对应,现在想要指定字段对应某个颜色 因为是直接在返回数据中做操作,所以直接写这部分的代码 数据格式 cdata: {xData: ["水文", "森林", "气象", "地质",…

学习笔记|外部中断|INT0|中断列表|STC32G单片机视频开发教程(冲哥)|第十五集:中断系统和外部中断

文章目录 1.中断和中断系统1.1什么是中断?1.2什么是中断系统1.3中断系统的优点1.4 中断系统包含哪些中断源1.5.中断次序 2.什么是外部中断3.外部中断的用法4.外部中断的用法完整代码 总结课后练习: 上节课我们学完了GPIO的矩阵按键,已经把这个GPIO的一个外设全都已…

最小二乘法的实现与线性回归的应用

1. 简介 简单线性回归中,您有一个因变量y和一个自变量X。该模型可以表示为: y m x b ymxb ymxb 其中 x x x: 自变量 y y y: 因变量 m m m: 斜率 b b b: 截距 最小二乘法是回归分析中用于估计线性回归模型参数的标准方法。它可以最小化误差的平方和&…