JVM图文入门

往期推荐

【已解决】redisCache注解失效,没写cacheConfig_com.howbuy.cachemanagement.client.redisclient#incr-CSDN博客

【已解决】OSS配置问题_keyuewenhua.oss-cn-beijing.aliyuncs-CSDN博客

【排坑】云服务器docker部署前后端分离项目+域名解析+OSS-CSDN博客

微服务概念入门:Nacos、OpenFeign、Sentinel、GateWay、Seata-CSDN博客

字符串常量池-CSDN博客

目录

1. JVM8结构图

2. Java性能低的主要原因

3. 字节码文件

3.1 字节码文件的组成

4. JVM架构

4.1 类加载器ClassLoader

4.2 运行时数据区

程序计数器

Java虚拟机栈(方法栈)

本地方法栈 

4.3 执行引擎

5. 双亲委派

5.1 破坏双亲委派

Tomcat破坏

JDBC破坏 


1. JVM8结构图

2. Java性能低的主要原因

Java语言如果不做任何的优化,性能其实是不如C和C++语言的。主要原因是:

在程序运行过程中,Java虚拟机需要将字节码指令实时地解释成计算机能识别的机器码,这个过程在运行时可能会反复执行,所以效率较低。

C和C++语言在执行过程中,只需将源代码编译成可执行文件,就包含了计算机能识别的机器码,无需在运行过程中再实时地解释,所以性能较高。

 Java为什么要选择一条执行效率比较低的方式呢?主要是为了实现跨平台的特性。Java的字节码指令,如果希望在不同平台(操作系统+硬件架构),比如在windows或者linux上运行。可以使用同一份字节码指令,交给windows和linux上的Java虚拟机进行解释,这样就可以获得不同平台上的机器码了。这样就实现了Write Once,Run Anywhere 编写一次,到处运行。

3. 字节码文件

我们java中说的字节码文件即 java代码编译后的.class文件,class文件可以跨平台运行在不同操作系统的JVM上。

3.1 字节码文件的组成

字节码文件总共可以分为以下几个部分:

  • 基础信息:魔数、字节码文件对应的Java版本号、访问标识(public final等等)、父类和接口信息

  • 常量池保存了字符串常量、类或接口名、字段名,主要在字节码指令中使用

  • 字段: 当前类或接口声明的字段信息

  • 方法: 当前类或接口声明的方法信息,核心内容为方法的字节码指令

  • 属性: 类的属性,比如源码的文件名、内部类的列表等

4. JVM架构

根据上面的JVM图,JVM大致可分为三块: 类加载器ClassLoader、运行时数据区 、执行引擎

4.1 类加载器ClassLoader

类加载器会通过二进制流的方式获取到字节码文件并交给Java虚拟机,虚拟机会在方法区和堆上生成对应的对象保存字节码信息。

根加载器(启动类加载器):

 默认加载Java安装目录/jre/lib下的类文件,比如rt.jar,tools.jar,resources.jar等。

扩展类加载器:

 默认加载Java安装目录/jre/lib/ext下的类文件

应用程序类加载器(系统类加载器):

 默认加载的是项目中的类以及通过maven引入的第三方jar包中的类。

用户自定义类加载器

输出为null是因为根加载器的具体实现是由C或C++编写,不在java范围内。 

4.2 运行时数据区

运行时数据可以划分为以下5块

程序计数器

每个线程都有一个私有的程序计数器,也就是一个指针,指向方法区中的方法字节码(用来存储指向指令的地址)。解释器会在工作的时候改变这个计数器的值来选取下一条需要执行的字节码指令。如果线程执行的是非本地方法,则程序计数器中保存的是当前需要执行的指令地址;如果线程执行的是本地方法,则程序计数器中的值是 undefined。

Java虚拟机栈(方法栈)

栈中没有垃圾回收的,线程结束后内存会自动释放。栈主管程序运行、生命周期、线程同步。

Java 虚拟机栈中是一个个栈帧,每个栈帧对应一个被调用的方法,当线程执行一个方法时,会创建一个对应的栈帧,并将栈帧压入栈中。当方法执行完毕后,将栈帧从栈中弹出。

栈帧及组成

  • 局部变量表,局部变量表的作用是在运行过程中存放所有的局部变量

  • 操作数栈,操作数栈是栈帧中虚拟机在执行指令过程中用来存放临时数据的一块区域

  • 帧数据,帧数据主要包含动态链接、方法出口、异常表的引用

stack1的方法结束后要弹出栈,此时需要通过stack1返回下面的stack2的方法。 

本地方法栈 

Java虚拟机栈存储了Java方法调用时的栈帧,而本地方法栈存储的是native本地方法的栈帧

public class Test {    public static void main(String[] args) {        Student s1 = new Student();        s1.name = "张三";       s1.age = 18;       s1.id = 1;s1.printTotalScore();        s1.printAverageScore();        Student s2 = new Student();       s2.name = "李四";        s2.age = 19;        s2.id= 2;        s2.printTotalScore();        s2.printAverageScore();    }
}

这段代码中通过new关键字创建了两个Student类的对象,这两个对象会被存放在堆上。在栈上通过s1s2两个局部变量保存堆上两个对象的地址,从而实现了引用关系的建立。

以前的Java 中“几乎”所有的对象都会在堆中分配,但随着JIT编译器的发展和逃逸技术的逐渐成熟,所有的对象都分配到堆上渐渐变得不那么“绝对”了。从 JDK 7 开始,Java 虚拟机已经默认开启逃逸分析了,意味着如果某些方法中的对象引用没有被返回或者未被外面使用(也就是未逃逸出去),那么对象可以直接在栈上分配内存。垃圾指JVM中没有任何引用指向它的对象

逃逸分析

逃逸分析是一种编译器优化技术,用于判断对象的作用域和生命周期。如果编译器确定一个对象不会逃逸出方法或线程的范围,它可以选择在栈上分配这个对象,而不是在堆上。这样做可以减少垃圾回收的压力,并提高性能。

一个JVM实例只有一个堆内存,堆内存大小可以调节,类加载器读取类文件后要把类、方法、常变量放到堆内存中,保存所有引用类型的真实信息,堆内存在逻辑上分为三部分:

  • 新生代:伊甸区、幸存0区 from、幸存1区 to
  • 老年代
  • 永久代

4.3 执行引擎

5. 双亲委派

应用程序类加载器(又叫系统类加载器)收到类的加载请求先检查自己是否加载过该类,如果没有,将请求向上委托给自己的父类加载器(extensionLoader),如果父类加载器也没有加载过该类,该父类加载器继续向上委托给自己的父类加载器(bootstrapLoader,又叫根加载器、启动类加载器)若启动类加载器也没有加载过该类,则会根据要加载的类的全限定名尝试加载该类,若加载成功,则返回引用,若加载失败,则抛出异常,并反向委托给扩展类加载器,若仍加载失败,则继续抛出异常,并反向委托给应用程序类加载器,若仍加载失败,则报异常ClassNotFound。

安全性和沙箱机制

由于java核心库和扩展库由根加载器加载,这些库中的类有更高的安全级别,而应用程序类由应用程序类加载器加载,安全级别低,双亲向上委派可以防止核心API被篡改,提高了程序安全性。

什么是沙箱?

java安全模型的核心就是java沙箱,沙箱是一个限制程序运行的环境,沙箱机制就是把java代码限定在jvm的特定运行范围内,严格限制代码对本地系统资源的访问(CPU、内存、文件系统、网络等),通过这样来保证代码的有效隔离,防止对本地系统造成破坏。

避免类重复加载

由于父类加载器加载类时会优先尝试加载,若类已经被加载过,就不会再次加载,避免了类重复加载。 

5.1 破坏双亲委派

打破双亲委派机制历史上有三种方式,但本质上只有第一种算是真正的打破了双亲委派机制:

  • 自定义类加载器并且重写loadClass方法。Tomcat通过这种方式实现应用之间类隔离。

  • 线程上下文类加载器。利用上下文类加载器加载类,比如JDBC和JNDI等。

  • Osgi框架的类加载器。历史上Osgi框架实现了一套新的类加载器机制,允许同级之间委托进行类的加载,目前很少使用。

Tomcat破坏

JDBC破坏 

JDBC中使用了DriverManager来管理项目中引入的不同数据库的驱动,比如mysql驱动、oracle驱动。DriverManager类位于rt.jar包中,由启动类加载器加载。依赖中的mysql驱动对应的类,由应用程序类加载器来加载。DriverManager属于rt.jar是启动类加载器加载的。而用户jar包中的驱动需要由应用类加载器加载,这就违反了双亲委派机制存疑

JDBC案例中真的打破了双亲委派机制吗?

最早这个论点提出是在周志明《深入理解Java虚拟机》中,他认为打破了双亲委派机制,这种由启动类加载器加载的类,委派应用程序类加载器去加载类的方式,所以打破了双亲委派机制。

但是如果我们分别从DriverManager以及驱动类的加载流程上分析,JDBC只是在DriverManager加载完之后,通过初始化阶段触发了驱动类的加载,类的加载依然遵循双亲委派机制。

所以我认为这里没有打破双亲委派机制,只是用一种巧妙的方法让启动类加载器加载的类,去引发的其他类的加载。

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

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

相关文章

Day37-【13003】短文,串的基本概念,匹配算法,算法时间复杂度,真题训练

文章目录 第二节 串串的基本概念串的模式匹配朴素的模式匹配算法(BF算法)算法最坏时间复杂度O(n x m) 改进的模式匹配算法(KMP算法)特征向量next,来确定k值特征向量next的算法实现 算法最坏时间复杂度O(n)进一步改进next值的计算,简化步骤 第四章真题真题…

GPU-Z重磅更新,Blackwell架构全面支持

由TechPowerUp倾力打造的GPU-Z,是一款集显卡信息查看、实时监控与深度诊断于一体的强大工具。它以其轻巧灵便的体积、完全免费的使用模式以及极其友好的操作界面,赢得了全球无数用户的青睐与信任,成为PC硬件领域中不可或缺的软件。 GPU-Z不仅…

leetCode刷题-图、回溯相关

岛屿数量 class Solution { private:int mi;int mj; public:int numIslands(vector<vector<char>>& grid) {mi grid.size() - 1; // i的范围 0~mimj grid[0].size() - 1; // j的范围 0~mjint landnum 0;bool sea false;do {pair<int, int> res …

VMware Win10下载安装教程(超详细)

《网络安全自学教程》 从MSDN下载系统镜像&#xff0c;使用 VMware Workstation 17 Pro 安装 Windows 10 consumer家庭版 和 VMware Tools。 Win10下载安装 1、下载镜像2、创建虚拟机3、安装操作系统4、配置系统5、安装VMware Tools 1、下载镜像 到MSDN https://msdn.itellyou…

基础篇05-直方图操作

本节将简要介绍Halcon中有关图像直方图操作的算子&#xff0c;重点介绍直方图获取和显示两类算子&#xff0c;以及直方图均衡化处理算子。 目录 1. 引言 2. 获取并显示直方图 2.1 获取&#xff08;灰度&#xff09;直方图 (1) gray_histogram (2) gray_histo_abs (3) gr…

Oracle(windows安装遇到的ORA-12545、ORA-12154、ORA-12541、ORA-12514等问题)

其实出现该问题就是监听或者服务没有配好。 G:\xiaowangzhenshuai\software\Oracle\product\11.2.0\dbhome_1\NETWORK\ADMINlistener.ora SID_LIST_LISTENER (SID_LIST (SID_DESC (SID_NAME CLRExtProc)(ORACLE_HOME G:\xiaowangzhenshuai\software\Oracle\product\11.2.0\d…

LabVIEW2025中文版软件安装包、工具包、安装教程下载

下载链接&#xff1a;LabVIEW及工具包大全-三易电子工作室http://blog.eeecontrol.com/labview6666 《LabVIEW2025安装图文教程》 1、解压后&#xff0c;双击install.exe安装 2、选中“我接受上述2条许可协议”&#xff0c;点击下一步 3、点击下一步&#xff0c;安装NI Packa…

在本地顺利的部署一个al模型从零开始 windows

引言 &#xff08;踩的坑&#xff0c;省流引言的内容没有有使模型跑起来&#xff09; 最近想在本地部署一个deepseek模型&#xff0c;就在网上搞了3 4天终于是能够部署下来了&#xff0c;在部署的时候也是成功的踩了无数的坑&#xff0c;比如我先问al如何在本地部署一个语言模…

基于ansible部署elk集群

ansible部署 ELK部署 ELK常见架构 &#xff08;1&#xff09;ElasticsearchLogstashKibana&#xff1a;这种架构是最常见的一种&#xff0c;也是最简单的一种架构&#xff0c;这种架构通过Logstash收集日志&#xff0c;运用Elasticsearch分析日志&#xff0c;最后通过Kibana中…

Linux学习笔记16---高精度延时实验

延时函数是很常用的 API 函数&#xff0c;在前面的实验中我们使用循环来实现延时函数&#xff0c;但是使用循环来实现的延时函数不准确&#xff0c;误差会很大。虽然使用到延时函数的地方精度要求都不会很严格( 要求严格的话就使用硬件定时器了 ) &#xff0c;但是延时函数肯定…

Linux系统 环境变量

环境变量 写在前面概念查看环境变量main函数的参数argc & argvenv bash环境变量 写在前面 对于环境变量&#xff0c;本篇主要介绍基本概念及三四个环境变量 —— PATH、HOME、PWD。其中 PATH 作为 “ 敲门砖 ”&#xff0c;我们会更详细讲解&#xff1b;理解环境变量的全局…

旋转变压器工作及解调原理

旋转变压器 旋转变压器是一种精密的位置、速度检测装置&#xff0c;广泛应用在伺服控制、机器人、机械工具、汽车、电力等领域。但是&#xff0c;旋转变压器在使用时并不能直接提供角度或位置信息&#xff0c;需要特殊的激励信号和解调、计算措施&#xff0c;才能将旋转变压器…

【漫话机器学习系列】076.合页损失函数(Hinge Loss)

Hinge Loss损失函数 Hinge Loss&#xff08;合页损失&#xff09;&#xff0c;也叫做合页损失函数&#xff0c;广泛用于支持向量机&#xff08;SVM&#xff09;等分类模型的训练过程中。它主要用于二分类问题&#xff0c;尤其是支持向量机中的优化目标函数。 定义与公式 对于…

基于docker搭建Kafka集群,使用KRaft方式搭建,摒弃Zookeeper

KAFKA基于docker使用KRaft进行集群搭建 环境&#xff1a;已成功搭建kafka服务 可点击链接跳转至安装kafka-3.8.0版本 并启用SASL认证 教程 使用基于Zookeeper方式搭建集群教程 kafka-3.8.0版本 并启用SASL认证 教程 搭建kafka-ui可视化工具 192.168.2.91 192.168.2.92 192…

Go 语言 | 入门 | 快速入门

快速入门 1.第一份代码 先检查自己是否有正确下载 Go&#xff0c;如果没有直接去 Go 安装 进行安装。 # 检查是否有 Go $ go version go version go1.23.4 linux/amd64然后根据 Go 的入门教程 开始进行学习。 # 初始化 Go 项目 $ mkdir example && cd example # Go…

凝思60重置密码

凝思系统重置密码 - 赛博狗尾草 - 博客园 问题描述 凝思系统进入单用户模式&#xff0c;在此模式下&#xff0c;用户可以访问修复错误配置的文件。也可以在此模式下安装显卡驱动&#xff0c;解决和已加载驱动的冲突问题。 适用范围 linx-6.0.60 linx-6.0.80 linx-6.0.100…

HTML 复习

文章目录 路径问题标题标签段落标签换行标签列表标签<ol> 有序列表<ul> 无序标签标签嵌套 超链接标签多媒体标签<img> 图片标签<audio> 音频标签<video> 视频标签 表格标签<colspan> 跨行<rowspan> 跨列组合使用 表单标签基本表单标…

hot100(8)

71.10. 正则表达式匹配 - 力扣&#xff08;LeetCode&#xff09; 动态规划 题解&#xff1a;10. 正则表达式匹配题解 - 力扣&#xff08;LeetCode&#xff09; 72.5. 最长回文子串 - 力扣&#xff08;LeetCode&#xff09; 动态规划 1.dp数组及下标含义 dp[i][j] : 下标i到…

114,【6】攻防世界 web wzsc_文件上传

进入靶场 传个桌面有的 直接空白了 我们 访问一下上传的东西 /index 没显示用于解析的.htaccess和.user.ini 文件&#xff0c;还两个都不显示 但上传的时候bp查看状态码是200&#xff0c;意味着上传成功了 别的博主说这是服务器在短时间内就立刻将其删掉了&#xff0c;需…

禅道社区版项目管理软件部署(记录篇)

系统要求&#xff08;这里推荐使用docker容器化方式&#xff09;安装前的准备Docker快速安装最后通过查看地址验证是否部署成功开始界面化安装配置 禅道&#xff08;ZenTao&#xff09;是一款国产开源的项目管理软件&#xff0c;专注于敏捷开发流程&#xff0c;支持 Scrum 和 K…