JVM知识汇总

news2025/1/20 6:04:42

 1、JVM架构图

2、Java编译器

Java编译器做的事情很简单,其实就是就是将Java的源文件转换为字节码文件

1. 源文件存储的是高级语言的命令,JVM只认识"机器码";

2. 因此将源文件转换为字节码文件,即是JVM看得懂的"机器码"文件。

3、类加载器

当程序需要用到某个类时,就需要加载对应的 .class 文件,然后在虚拟机中创建对应的class对象,这一个过程就是类加载器做的事情。

类的加载过程包括以下五个步骤:

<1> 加载:通过类的全限定名查找对应的字节码文件,并通过该字节码文件生成对应的类对象;

<2> 验证:验证类文件的二进制字节码文件是否符合虚拟机的规范,或者说有损虚拟机的运行,包括文件格式验证,元数据验证,字节码验证,符号引用验证;

<3> 准备:对一些类变量赋初始值(例如,static int a;=> static int a = 0);

<4> 解析:虚拟机将常量池内的符号引用替换为直接引用的过程,解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行。符号引用就是一组符号来描述目标,可以是任何字面量(直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄);

<5> 初始化:对所有变量进行赋值,包括类变量和成员变量。

细心阅读你会发现:为什么第<2>步验证是验证二进制字节码文件,那为什么不验证后在通过<1>将其字节码文件生成对象呢?

-------------------------------------------------------------------------------------------------------------

其实它们并不是串行的,在<1>将字节码文件加载到内存的时候,此时就会启动<2>对其二进制字节码文件进行验证了!

JVM提供了三种类加载器:

<1> Bootstrap ClassLoader,启动类加载器:加载<JAVA_HOME>/lib目录下的类文件;

<2> Extension ClassLoader,拓展类加载器:加载<JAVA_HOME>/lib/ext目录下的类文件;

<3> Application ClassLoader,引用类加载器:加载 java.class.path 目录下的类文件;

三者配合使用(当然JVM还支持自定义类加载器,为了方便描述,这里就不谈它了),配置机制就是总所周知的双亲委派机制,执行流程如下:

备注:三个类加载器不是继承的关系,但是为了方便,我称在下面的类加载器为子加载器,在上面的加载器为父加载器!

每次需要加载类的时候,类加载器不会直接去加载,而是委托其父加载器去执行,一直委托到Bootstrap ClassLoader,Bootstrap ClassLoader不存在该类才一步步往下退给子加载器。

双亲委派机制的作用:

保护核心API库的作用,假设从网络中传输一个名为 java.lang.Integer的文件过来,如果不通过父类加载器进行验证,在Application ClassLoader就进行加载,那原本的 java.Integer.Integer核心API库就完全被篡改了,这在JVM上是不允许的。

4、运行时数据区

运行时数据区模块可分为五个子模块:

<1> 堆(线程共享):存放new出来的对象(少量对象逃逸分析在栈中);

<2> 方法区(线程共享):存放类的所有信息,即是创建对象所需的原材料(有点Spring创建Bean的原材料那个BeanDefinition的味道),通过反编译命令可以看看到底存的啥:

javap -v -p Order.class > text.txt

常量池其实就是一些字面量和符号引用真实值的一些映射,如果直接存放数据,可能内存会直接爆了,所以存个引用地址就可以啦。

<3> 虚拟机栈(线程私有):每一个线程都有独享一个虚拟机栈,它的生命周期与线程相同。每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

<4> 本地方法栈(线程私有):本地方法栈与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。

<5> 程序计数器(线程私有):它的作用就是记录当前线程所执行的位置。 这样,当线程重新获得CPU的执行权的时候,就直接从记录的位置开始执行,分支、循环、跳转、异常处理也都依赖这个程序计数器来完成。

5、垃圾收集器

垃圾收集器,主要是对不再使用的对象进行回收,而这些不再使用的对象就被JVM成为垃圾,那怎么判断一个对象是否为垃圾呢?

垃圾:GC-Roots所不能到达的对象则称为垃圾。

可作为GC-Root的对象:

1. Java虚拟机栈中被引用的对象,各个线程调用的参数、局部变量、临时变量等;

2. 方法区中类静态属性引用的对象,比如引用类型的静态变量;

3. 方法区中常量引用的对象;

4. 本地方法栈中所引用的对象;

5. Java虚拟机内部的引用,基本数据类型对应的Class对象,一些常驻的异常对象;

6. 被同步锁(synchronized)持有的对象。

5.1 垃圾回收算法

存在这三种垃圾回收算法,分别是:标记-清除、标记-复制、标记-整理。

5.1.1 标记-清除

规则:标记垃圾对象,然后清除。

优点:实现简单

缺点:存在内存碎片(碎片:不够创建其他对象的空间,这块空间则称为碎片空间)

5.1.2 标记-复制

 规则:分为两块空间,每次只使用一块空间,然后将存活的对象移动另一块空间。

优点:避免内存碎片

缺点:需要多一块空间,则表明浪费了一块空间

5.1.3 标记-整理

 规则:标记垃圾对象,然后清除,最后整理以下存活对象的空间位置

优点:避免了内存碎片

缺点:整理对象需要损耗大量的时间

5.2 垃圾收集器

 垃圾收集器其实就是垃圾算法的一些工程落地实现。

5.2.1 Serial

 Serial收集器作用于新生代,采用标记-复制算法,使用单核处理器进行垃圾回收,没有过多线程之间的交互,在单核处理器下表现出很好的性能。

5.2.2 ParNew

 ParNew收集器作用于新生代,采用标记-复制算法,除了GC过程采用多条线程进行垃圾回收之外,其他的与Serial收集器一样。

5.2.3 Parallel Scavenge

Parallel Scavenge收集器也是一款新生代收集器,基于标记——复制算法实现,能够并行收集的多线程收集器和 ParNew 非常相似。

Parallel Scavenge 收集器的目标则是达到一个可控制的吞吐量(Throughput)。所谓吞吐量就是处理器用于运行用户代码的时间与处理器总消耗时间的比值。如果虚拟机完成某个任务,用户代码加上垃圾收集总共耗费了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。

Parallel Scavenge 收集器提供了两个参数用于精确控制吞吐量,分别是控制最大垃圾收集停顿时间的 -XX:MaxGCPauseMillis 参数和直接设置吞吐量大小的-XX:GCTimeRatio参数。

5.2.4 Serial Old

 Serial Old与Serial一样的垃圾回收原理,但是采用标记-整理算法,作用于老年代。

5.2.5 Parallel Old

Parallel Old与ParNew一样的垃圾回收原理,但是采用标记-整理算法,作用于老年代。 

5.2.6 CMS

 CMS,标记清除算法,作用于老年代。

GC过程主要分为以下四个流程:

<1> 初始标记:标记GC-Root能直接关联的对象,该过程需要发生Stop The World

<2> 并发标记:该过程用户线程与GC线程并发执行,补充GC-Root完整链路

<3> 重新标记:因为并发标记阶段用户线程也在执行,所以可能会出现漏标、错标情况,因此在该阶段发生Stop The World,解决漏标、错标问题

<4> 并发清除:清除垃圾对象

优点:减少了Stop The World的时间

缺点:会产生浮动垃圾,同时标记-清除算法,会存在内存碎片

5.2.7 G1

G1收集器采用“标记-复制”和“标记-整理”。从整体上看是基于“标记-整理”,从局部看,两个region之间是“标记-复制”。

G1收集器的出现,使得JVM不再区分新生代和老年代,统一处理,将堆划分为均等分的Region。

GC过程主要分为以下四个流程:

<1> 初始标记:标记GC-Root能直接关联的对象,该过程需要发生Stop The World

<2> 并发标记:该过程用户线程与GC线程并发执行,补充GC-Root完整链路

<3> 最终标记:因为并发标记阶段用户线程也在执行,所以可能会出现漏标、错标情况,因此在该阶段发生Stop The World,解决漏标、错标问题

<4> 筛选回收:在给定的GC时间内,选择最优价值的垃圾进行回收。

三色标记法:

三色标记法,将对象分为黑、灰、白色。

黑色节点表示经过GC-Root遍历过的节点,灰色节点表示下一次遍历的节点,白色节点表示GC-Root到不了的节点。 等待标记完毕,剩下黑色、白色两种。黑色是使用中的对象,白色为垃圾对象,因此对其白色进行回收即可。

5.3 GC类型

5.3.1 Young GC

针对新生代的GC,当新生代的垃圾达到回收条件,会触发Young GC。

5.3.2 Full GC

针对整个堆和方法区的GC,当老年代的垃圾达到回收条件,会触发Full GC。


关于CMS与G1的对比,以及为什么能一边GC一边执行用户线程(三色标记法),Ysming88博主这篇文章讲得挺好的;同时垃圾收集器部分,参考了楼仔文章的解释。

总结:

* 新生代用“复制算法”,老年代基本用“标记-整理”算法(有的也用“标记-清除”算法),(新生代因为有surive区域,所以肯定使用的“复制算法”,老年代不可能划分成2个区域,所以肯定不会使用“复制算法”);

* 单线程垃圾回收器:Serial、Serial Old;

* 多线程垃圾回收器:ParNew、Parallel Old、Pararrel Scavenge和G1;

* 适用新生代的垃圾回收器:Serial、ParNew、Pararrel Scavenge和G1;

* 适用老年代的垃圾回收器:Serial Old、Parallel Old和G1。

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

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

相关文章

Node.js—Buffer(缓冲器)

文章目录 1、概念2.、特点3、创建Buffer3.1 Buffer.alloc3.2 Buffer.allocUnsafe3.3 Buffer.from 4、操作Buffer4.1 Buffer 与字符串的转化4.2 Buffer 的读写 参考 1、概念 Buffer 是一个类似于数组的对象 &#xff0c;用于表示固定长度的字节序列。Buffer 本质是一段内存空间…

视觉学习(四) --- 基于yolov5进行数据集制作和模型训练

环境信息 Jetson Xavier NX&#xff1a;Jetpack 4.4.1 Ubuntu&#xff1a;18.04 CUDA: 10.2.89 OpenCV: 4.5.1 cuDNN&#xff1a;8.0.0.180一.yolov5 项目代码整体架构介绍 1. yolov5官网下载地址&#xff1a; GitHub: https://github.com/ultralytics/yolov5/tree/v5.0 2. …

单元测试中的独立运行

单元测试中的独立运行 单元测试是针对代码单元的独立测试。要测试代码单元&#xff0c;首先要其使能够独立运行。项目中的代码具有依赖关系&#xff0c;例如&#xff0c;一个源文件可能直接或间接包含大量头文件&#xff0c;并调用众多其他源文件的代码&#xff0c;抽取其中的一…

论文阅读:Unsupervised Manifold Linearizing and Clustering

Author: Tianjiao Ding, Shengbang Tong, Kwan Ho Ryan Chan, Xili Dai, Yi Ma, Benjamin D. Haeffele Abstract 在本文中&#xff0c;我们建议同时执行聚类并通过最大编码率降低来学习子空间联合表示。 对合成和现实数据集的实验表明&#xff0c;所提出的方法实现了与最先进的…

limit、排序、分组单表查询(三)MySQL数据库(头歌实践教学平台)

文章目的初衷是希望学习笔记分享给更多的伙伴&#xff0c;并无盈利目的&#xff0c;尊重版权&#xff0c;如有侵犯&#xff0c;请官方工作人员联系博主谢谢。 目录 第1关&#xff1a;对查询结果进行排序 任务描述 相关知识 对查询结果排序 指定排序方向 编程要求 第2关&a…

浏览器架构和事件循环

浏览器架构 早期浏览器【单进程多线程】 Page Thread 页面渲染&#xff0c;负责执行js,plugin,drawNetWork Thread 网络请求其余线程 file, storage缺点&#xff1a;只要其中一个线程崩溃&#xff0c;页面就会崩溃。 现代浏览器架构 多进程的浏览器&#xff0c;浏览器的每一个…

几种常见的激活函数

文章目录 常见的激活函数介绍Sigmoid函数ReLU函数LeakyReLU函数Tanh函数Softmax函数总结 常见的激活函数介绍 激活函数是神经网络中的重要组成部分&#xff0c;它决定了神经元的输出。在神经网络的前向传播中&#xff0c;输入数据被传递给神经元&#xff0c;经过加权和和激活函…

Unity自动化打包(1)

一 安装Jenkins https://www.jenkins.io/download/ 官网 1&#xff09; 使用 brew 安装 2&#xff09; 安装完成后一般都会遇到问题 我用的是jenkins-lts 稳定版 解决办法 删除掉对应的文件夹 1 rm -rf /usr/local/Homebrew/Library/Taps/homebrew/homebrew-services 2…

kafka延时队列内部应用简介

kafka延时队列_悠然予夏的博客-CSDN博客 两个follower副本都已经拉取到了leader副本的最新位置&#xff0c;此时又向leader副本发送拉取请求&#xff0c;而leader副本并没有新的消息写入&#xff0c;那么此时leader副本该如何处理呢&#xff1f;可以直接返回空的拉取结…

[ 高并发]Java高并发编程系列第二篇--线程同步

并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求,而且也能怎么你在整个项目中的一个处理逻辑的能力体现.那么,你真的知道什么…

ThreadLocal 内存泄露的原因及处理方式

1、ThreadLocal 使用原理 ThreadLocal的主要用途是实现线程间变量的隔离&#xff0c;表面上他们使用的是同一个ThreadLocal&#xff0c; 但是实际上使用的值value却是自己独有的一份。用一图直接表示threadlocal 的使用方式。 从图中我们可以当线程使用threadlocal 时&#xf…

CRC校验原理及其使用

目录 何为CRC 为什么需要校验 为什么是CRC CRC的缺点 目录 何为CRC 为什么需要校验 为什么是CRC CRC的缺点 如何进行CRC校验 校验标准式是什么玩意&#xff1f; 常见的CRC校验 CRC校验计算过程 CRC校验代码参考 代码解读 生成CRC8校验表的代码 CRC检验网站 如何…

GEE:使用 VCT(Vegetation Change Tracker)算法森林进行时序变化检测分析

作者: _养乐多_ 本文将介绍一段 Google Earth Engine 的代码,该代码用于进行时序变化检测分析,即使用 VCT(Vegetation Change Tracker)算法对某一地区的多年影像进行分析,得出每一年的变化程度,并输出一个 VCT 矩阵,同时还可根据矩阵得到每一年的变化遥感图。可以分析…

时下热门话题:ChatGPT能否取代人类?

时下热门话题&#xff1a;ChatGPT能否取代人类&#xff1f; 2022年11月底&#xff0c;人工智能对话聊天机器人ChatGPT推出&#xff0c;迅速在社交媒体上走红&#xff0c;短短5天&#xff0c;注册用户数就超过100万。2023年1月末&#xff0c;ChatGPT的月活用户已突破1亿&#x…

迭代器设计模式(Iterator Design Pattern)[论点:概念、组成角色、相关图示、示例代码、框架中的运用、适用场景]

概念 迭代器设计模式&#xff08;Iterator Design Pattern&#xff09;是一种行为型设计模式&#xff0c;它提供了一种方法来顺序访问一个聚合对象&#xff08;如集合&#xff09;的元素&#xff0c;而不需要暴露该对象的底层表示。迭代器模式可以帮助我们在不关心底层数据结构…

红酒分类案例中使用分箱处理

红酒分类案例中使用分箱处理 描述 在建立分类模型时&#xff0c;通常需要对连续特征进行离散化(Discretization)处理 &#xff0c;特征离散化后&#xff0c;模型更加稳定&#xff0c;降低了过拟合风险。离散化也叫分箱(binning)&#xff0c;是指把连续的特征值划分为离散的特…

Binder Driver 初探从驱动层角度来看

1&#xff1a;驱动概述 1.1基本简介 Binder 驱动是 Android 专用的&#xff0c;但底层的驱动架构与Linux 驱动一样。binder 驱动在以 misc 设备进行注册&#xff0c;作为虚拟字符设备&#xff0c;没有直接操作硬件&#xff0c;只是对设备内存的处理。主要是驱动设备的初始化(b…

如何刻录光盘文件

常识补充刻录机简介光盘刻录机是一种数据写入设备&#xff0c;利用激光将数据写到空光盘上从而实现数据的储存。其写入过程可以看做普通光驱读取光盘的逆过程。基本原理刻入数据时&#xff0c;利用高功率的激光束反射到盘片&#xff0c;使盘片上发生变化&#xff0c;模拟出二进…

计算机网络常见协议

文章目录 计算机网络TCP/IP协议TCP协议的三次握手和四次挥手TCP连接建立过程TCP连接断开过程为什么要三次握手&#xff1f;为什么要四次挥手&#xff1f; UDP协议HTTP协议 计算机网络 学习计算机网络&#xff0c;来记录一下。 TCP/IP协议 TCP/IP协议是Internet最基本的协议、…

报错-crontab -e 定时任务执行失败排查

使用 crontab -e 定时启动 jar 包服务失败&#xff0c;排查过程如下&#xff1a; 1、查看 crontab 服务 crontab -l陈列出了待执行任务列表&#xff0c;crontab 正常。 2、检查脚本 单独执行脚本没有问题&#xff0c;脚本内容为检查线程&#xff0c;杀死线程&#xff0c;重…