《码出高效:Java开发手册》 四-走进JVM

news2025/1/17 16:17:11

前言

JVM是java中底层的知识,这里的内容比较复杂,对于一些软件编程,会经常使用,但很多业务其实碰不到这里的知识,下图为目录
在这里插入图片描述

介绍

JVM,java虚拟机,它的前身是99年的hotspot java虚拟机,之后被oracle收购后,形成了现在的OpenJDK使用的主流JVM
一些商业公司都有自己的定制版本,比如阿里有AJDK

字节码

之前讲01是最底层的信号,而再向上就是机器码,不同的操作系统,硬件都会对应不同种类的机器码,这就需要针对多种平台编写不同代码,而jvm可以做到在不同平台都字节码来运行,字节码bytecode大小为一个字节(8位),可以存储256种不同的指令,java有200个左右的指令

  • 主要的字节码指令
    1.加载和存储指令
    将局部变量加载到操作栈中:如ILOAD,ALOAD等
    将操作栈顶存储到局部变量表:ISTORE,ASTORE等
    常量加载到操作栈顶,使用频率高:ICONST,BIPUSH,SIPUSH,LDC等
    2.运算指令
    3.类型转换指令
    4.对象创建与访问指令
    5.操作栈管理指令
    6.方法调用与返回指令
    7.同步指令
    -编写好的java文件是源代码,需要转换为字节码才能给机器执行,转化流程如下
    在这里插入图片描述

字节码需要通过类加载过程加载到JVM环境后,才可以执行
执行方法有三种:
解释执行
JIT编译执行
JIT与解释执行混合(主流JVM默认执行方式)

  • JIT作用是将字节码动态编译成可以直接发给处理器指令执行的机器码,简要流程如下
  • 在这里插入图片描述
    书中讲了一个实例:机器在刚启动时,负载比较低,之后会慢慢升高,有程序员在发布时直接分为两批发布,导致前一半机器宕机,说明了JVM刚启动时,JIT动态编译和热点代码统计还没开始,此故障说明了JIT的存在

类加载过程

任何程序都需要加载到内存才能与CPU进行交流,字节码.class文件同样需要加载到内存中,才可以实例化类

  • Java的类加载器主要有三个流程,Load,Link,Init
  • Load,加载类文件的二进制流,转化为特定数据结构,校验各种参数后,创建对应类的java.lang.Class实例
  • Link,包括准备,验证,解析三步,这里的验证相比之前更加详细,对类型,变量进行检查,准备就是分配内存,布局内存结构
  • Init,执行构造器clinit方法,如果有其他类的静态方法参与,就解析另外一个类
  • 在这里插入图片描述
    这里还讲了class是Class(注意大小写)的对象,也就是类是Class的抽象
    这里不太明白,只留下大概代码,以后去理解
    在这里插入图片描述
    在这里插入图片描述
    执行结果是
    在这里插入图片描述
    这个示例说明了类的一些加载特性,类加载器把类的实现和定义解耦了,同时可以用2的方法获取注解,方法等
    类加载器的结构,分Bootstrap,platform ClassLoader(平台类加载器),Application ClassLoader的应用类加载器。用户也可以自定义类加载器,查看本地类加载器方式如下:
    在这里插入图片描述
    JDK8下的输出
    在这里插入图片描述
    下图显示的是类加载器间的关系
    在这里插入图片描述
  • 低层次的类加载器在加载类之前会向上逐级询问,这个类是否以加载
    高层次类加载器会检查是否已经加载此类,以及是是否可以加载此类
    通常流程是:向上问是否已加载此类,如果没有,之后向下问是否可加载,如果不能,就让当前类加载器去加载这个类,当然实际类库比图中要多
  • Bootstrap加载的路径可以追加,不建议修改或者删除原有路径
  • 自定义类加载器的情况
    1.隔离加载类:在某些框架中进行中间件与应用模块隔离,比如需要确保应用依赖的jar包不会影响中间件运行时使用的jar包
    2.修改类加载方式,Boostrap外的加载并非一定要引入
    3.扩展加载源,比如从数据库,网络甚至机顶盒进行加载
    4.防止源代码泄露
  • 实现自定义类加载器的步骤:继承ClassLoader ,重写findClass()方法,调用defineClass() 方法。
  • 如下为一个简单的类加载器
  • 在这里插入图片描述

内存布局

在这里插入图片描述
上图即为经典JVM布局

  • 堆:堆区是OOM故障多发地,大量创建对象,容易消耗完堆内存,可以调整大小,-xms,-xmx,一般保持一样大小,在线上环境可以避免GC后调整堆大小时带来额外压力
    堆里对象的晋升流程如图在这里插入图片描述
  • 给JVM 设置运行参数-XX:+HeapDumpOnOutOfMemoryError ,可以让JVM在OOM异常时能输出堆内信息
    • 元空间
      元空间的前身是永久代,由于很难调优,经常出现致命错误,后来用元空间替代后,转为再本地内存中分配
      3.JVM Stack(虚拟机栈)
      栈就是先进后出,像弹夹一样,它是线程私有的,用于进行方法调用
      栈帧:就是栈顶的,只有这里的帧才是有效的,也就是当前栈帧,它是方法运行的基本结构,执行引擎运行时,只能操作当前栈帧
      StackOverflowError表示请求的栈溢出,导致内存耗尽,通常出现在递归方法中
  • 栈帧包括了局部变量表,操作栈,动态连接,方法返回地址等
  • 局部变量表:存放方法参数和局部变量
  • 操作栈:初始状态为空的桶式结构栈,里面会压入弹出一些指令,与局部变量表进行交互
    以一个常见的面试题:i++和++i为例子,在字节码层面是这样的
    在这里插入图片描述
    左边:局部变量表中取出一个数,压入栈顶,下一步实现+1操作,对栈顶元素无影响,接下来把栈顶元素赋值给a
    右边:先做完+1操作后,压入栈顶,之istore_2后存进去的就是i+1的值
    这里i++不是原子操作,即使用volatile修饰,多个线程下也会产生数据覆盖问题
  • 动态连接:每个栈帧中有一个对当前方法的应用,就是动态连接
  • 方法返回地址:方法执行时有两种退出情况:正常退出和异常退出
    4.本地方法栈
    本地方法栈是线程私有的,虚拟机栈主JVM内部,本地方法栈则主JVM外部
    5 .程序计数器
    这里的计数器指的是CPU的寄存器,这里主要是保证指令之间连贯执行,多线程之间互不影响
    从公有私有角度可以为JVM分为以下
    在这里插入图片描述

对象实例化

从Object ref = new Object()分析,查看字节码如下
在这里插入图片描述

  • 从字节码角度看待对象创建过程
    new:无CLass对象则进行类加载,之后分配堆内存,零值初始化,将指向实例变量的引用变量压入虚拟机栈顶
    Dup:在栈顶复制该引用变量,如果 方法有参数,需要把参数压入操作栈,两个引用变量的目的不同,压至底下的用于赋值,栈顶的作为句柄调用相关方法
    INVOKESPECIAL:调用对象实例方法,通过栈顶调用init方法,clinti是类初始化方法,inti是对象初始化方法
  • 从执行步骤分析对象创建过程
    确定类元信息是否存在,这里找不到class文件就会抛出ClassNotFound异常
    分配对象内存,计算对象占用空间,在堆中划分内存,这里有同步操作,一般是CAS失败重试或者区域加锁等
    设定默认值
    设置对象头,包括哈希码,GC,锁信息,类元信息
    执行init方法,初始化成员变量,执行实例化代码块,调用类的构造方法,引用变量接收对象首地址

垃圾回收

垃圾回收,简称GC,判断内存不足且虚拟机空闲时,就会清除不再使用的对象,自动释放内存

  • 判断逻辑:GC Roots,对象与其roots之间没有引用关系(包括间接),就可以被回收
  • 回收方法:标记清除:直接清除不用的对象,会产生大量内存碎片
    标记整理:将可以存活对象整理到内存一端,把边界之外的都清除掉
    复制:MArk-coy,分两块空间,回收时把可存活对象放到另一块上,之后清除原对象
    新生代使用复制,老生代标记整理
  • 垃圾回收器:有数十种,常用的有serial,CMS,G1

在这里插入图片描述

G1采用标记清除,可以配置-XX :+UseCMSCompactAtFul!Collection参数,强制full gc后对老年代进行压缩,也就是空间碎片整理,可以配置XX : +CMSFul!GCsBeforeCompaction=n 参数,防止频繁整理引发STW(暂停整个应用程序执行)
在这里插入图片描述

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

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

相关文章

vue 计算属性未重新计算 / computed 未触发 / computed 原理源码分析

点击可打开demo 这里在一秒后改了数组里value属性的值 虽然数据有更新,但打开控制台,可以发现computed函数只在初始化时执行了一次 按理说一秒后改变了value值,应该执行两次才对呀? 但如果computed属性这样写,明确写…

数据分析之大数据分析

一 什么是大数据分析 大数据是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。大数据的特点可以概括为5个V:数据量大&…

当湿度达到70蜂鸣器警报

1.编写设备树&#xff0c;添加蜂鸣器等设备 驱动代码&#xff1a; #include <linux/init.h> #include <linux/module.h> #include <linux/i2c.h> #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/device.h> #include …

QCSPCChart for Java R3x0 Crack

Java 的 SPC 控制图工具 版本 3.04 QCSPCChart添加变量控制图&#xff08;X-Bar R、X-Bar Sigma、Individual Range、Median Range、EWMA、MA、MAMR、MAMS 和 CuSum 图&#xff09;、属性控制图&#xff08;p-、np-、c-、u- 和DPMO 图&#xff09;、频率直方图和 Pareto 图到…

[附源码]Python计算机毕业设计Django的旅游景点管理系统的设计与实现

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

[附源码]Python计算机毕业设计SSM老年公寓管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

计算机编程

文章目录计算机编程计算机编程语言计算机编程 人与人之间信息&#xff08;如想法、思想等&#xff09;的交流和传递&#xff0c;需要借助双方都能听得懂的语言。人和计算机之间实现交流也是如此&#xff0c;需要借助一种人和计算机都能理解的语言&#xff0c;这种语言称为编程…

LCHub低代码社区:旧的低代码,腾讯怎么讲出新故事

腾讯微搭的对手从来都不是钉钉。 低代码是 " 旧瓶装新酒 " 吗? 低代码风潮在国内兴盛已有两年,但也并不是已经被所有人接受,有不少开发者还保有否定、抵触的态度。 那为什么我们还认为这是一个不可逆的趋势呢? 这里先看下被否定的原因,LCHub在调研中听到的主…

怎么把PDF转换成图片?这三种转换方法都可以实现

怎么把PDF文件的内容转换成图片来使用呢&#xff1f;大家在办公或者是学习的过程中没少使用过PDF文件&#xff0c;有的文件我们翻阅起来会比较费时间&#xff0c;因为文件的内容多&#xff0c;这时候我们只需要把文件内容转成图片就可以解决这一问题&#xff0c;想要使用哪部分…

手把手带你开发你的第一个前端脚手架

开发一个简单的脚手架 1.创建 npm 项目 首先创建一个文件夹&#xff0c;然后进入到该文件夹目录下&#xff0c;执行 npm init -y 2.创建脚手架入口文件bin/index.js&#xff0c;在index.js中添加如下代码 #!/usr/bin/env nodeconsole.log(hello cli) 3.配置 package.json&a…

YOLOv5如何训练自己的数据集

目录 一、标注 1.1 标注软件下载labelimg 下载地址&#xff1a;mirrors / tzutalin / labelimg GitCode 1.2 json转txt 1.3 xml转txt 二、修改配置文件 2.1 建立文件目录 2.2 修改wzry_parameter.yaml文件 三、开始训练 3.1 2.结果 四、识别检测detect.py 1.调参找…

Jetson NX系统烧录以及CUDA、cudnn、pytorch等环境的安装

安装虚拟机和Ubuntu18.04环境 这两步比较简单&#xff0c;所以略了。虚拟机的配置需要注意硬盘空间大一点&#xff0c;至少40G。 安装sdk-manager NVIDIA SDK Manager下载地址&#xff1a;https://developer.nvidia.com/drive/sdk-manager sudo dpkg -i sdkmanager_1.9.0-…

YOLOv5和YOLOv7环境(GPU)搭建测试成功

本来是用doc写的&#xff0c;直接复制到这里很多图片加载缓慢&#xff0c;我直接把doc上传到资源里面了&#xff0c;0积分下载&#xff1a; (10条消息) YOLOv5和YOLOv7开发环境搭建和demo运行-Python文档类资源-CSDN文库 一、环境搭建 1.1 环境搭建参考链接 YOLO实践应用之…

uni-app 超详细教程(一)(从菜鸟到大佬)

一&#xff0c;uni-app 介绍 &#xff1a; 官方网页 uni-app 是一个使用 Vue.js 开发所有前端应用的框架&#xff0c;开发者编写一套代码&#xff0c;可发布到iOS、Android、Web&#xff08;响应式&#xff09;、以及各种小程序&#xff08;微信/支付宝/百度/头条/飞书/QQ/快手…

百度集团副总裁吴甜发布文心大模型最新升级,AI应用步入新阶段

11月30日&#xff0c;由深度学习技术与应用国家工程研究中心主办、百度飞桨承办的WAVE SUMMIT2022深度学习开发者峰会如期举行。百度集团副总裁、深度学习技术及应用国家工程研究中心副主任吴甜带来了文心大模型的最新升级&#xff0c;包括新增11个大模型&#xff0c;大模型总量…

PyQt5_寻找顶(底)背离并可视化

技术指标的背离是指技术指标曲线的波动方向与价格曲线的趋势方向不一致&#xff0c;是使用技术指标最为重要的一点。在股市中&#xff0c;常见的技术指标的背离分为两种常见的形式&#xff0c;即顶背离和底背离。背离是预示市场走势即将见顶或者见底的依据&#xff0c;在价格还…

计算机组成原理习题课第四章-1(唐朔飞)

计算机组成原理习题课第四章-1&#xff08;唐朔飞&#xff09; ✨欢迎关注&#x1f5b1;点赞&#x1f380;收藏⭐留言✒ &#x1f52e;本文由京与旧铺原创&#xff0c;csdn首发&#xff01; &#x1f618;系列专栏&#xff1a;java学习 &#x1f4bb;首发时间&#xff1a;&…

k8s部署手册

一、基础配置 1.修改主机名 hostnamectl set-hostname k8s-master01 hostnamectl set-hostname k8s-master02 hostnamectl set-hostname k8s-master03 hostnamectl set-hostname k8s-node01 hostnamectl set-hostname k8s-node022.添加 主机名与IP地址解析 cat > /etc/hos…

LINUX安装openssl

openssl 官网下载 https://www.openssl.org/source/old/ 1、解压openssl包&#xff1a; tar -xzf openssl-1.1.1n.tar.gz2、得到openssl-1.1.1n目录&#xff0c;然后进入openssl-1.1.1n目录中&#xff0c;安装openssl到 /usr/local/openssl 目录&#xff0c;安装之后&#xff…

[附源码]Python计算机毕业设计SSM联动共享汽车管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…