JVM资料阅读笔记总结-1

news/2024/5/18 18:00:54/文章来源:https://blog.csdn.net/weixin_40803011/article/details/126547085

前言

  最近读周志明的《深入理解Java虚拟机》以及半栈工程师的Java虚拟机文章,对JVM又重新复习了一遍,每次看后收获都不一样(因为没有debug能力,还是很懵懂),担心会忘记将自己读后总结记录下来

总结内容

java代码怎样被操作系统执行

  1. java先编译成二进制形式的java字节码放在Class文件

  2. 通过jclasslib bytecode viewer插件查看class文件基本格式
    在这里插入图片描述
    2.1 Class类文件的结构(参考《Java虚拟机规范》)
    (1)魔数与Class文件的版本
    (2)常量池
    (3)访问标志
    (4)类索引、父类索引与接口索引集合 // 继承关系
    (5)字段表集合
    (6)方法表集合
    (7)属性表集合

  3. 当运行过程中需要这个类时进行类加载
    3.1 配置-XX:+TraceClassLoading JVM参数监控类的加载 在这里插入图片描述
    3.2 当虚拟机启动时,用户需要指定一个要执行的主类,虚拟机会先初始化这个主类
    3.3 利用ClassFileStream加载class文件转成文件流
    3.4 调用ClassFileParser解析文件流生成JVM的数据结构InstanceKlass
    (1)在Metaspace(元空间)为 InstanceKlass 分配内存
    (2)分析Class文件,填充 InstanceKlass 内存区域
    3.5 Dictionary保存ClassLoader加载过的类信息

  4. 调用主类的main方法
    4.1 分配方法对应的Method,将解析方法时读取到信息填充到Method中
    4.2 在调用类的static方法时初始化InstanceKlass,调用 link_class()对类进行链接
    4.3 最终是通过StubRoutines::call_stub()的返回值来调用java方法的
    4.4 通过method找到对应的entry_point例程,并传递给call_stub例程
    (1)当方法链接时,会去设置方法的entry_point
    (2)例程可以理解为用汇编写好的一个方法
    4.5 call_stub准备好堆栈后,就开始前往entry_point处
    4.6 entry_point例程就会开始执行传递给它的Java方法了

方法

在这里插入图片描述

运行时栈帧结构

Java虚拟机以方法作为最基本的执行单元,“栈帧”(Stack Frame)则是用于支持虚拟机进行方法 调用和方法执行背后的数据结构
在这里插入图片描述

  1. 局部变量表:用于存放方法参数和方法内部定义的局部变量
    1.1 在方法的Code属性的max_locals数据项中确定了该方 法所需分配的局部变量表的最大容量
    1.2 reference类型表示对一个对象实例的引用
    (1)根据引用直接或间接地查找到对象在Java堆中的数据存放的起始地址或索引
    (2)根据引用直接或间接地查找到对象所属数据类型在方法区中的存储的类型信息
    1.3 returnAddress类型已经全部改为采用异常表来代替了
    1.4 如果执行的是实例方法,那局部变量表中第0位索引的变量槽默认是用于传递方法所属对象实例的引用

  2. 操作数栈
    2.1 操作数栈的最大深度也在编译的时候被写入到Code属性的max_stacks数据项之中
    2.2 操作数栈中元素的数据类型必须与字节码指令的序列严格匹配
    在这里插入图片描述

  3. 动态链接
    3.1 每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用
    3.2 字节码中的方法调用指令就以常量池里指向方法的符号引用作为参数

基于栈的解释器执行过程

  1. 根据下面代码来描述执行过程中操作数栈和局部变量表的变化情况
    在这里插入图片描述
  2. 首先执行偏移地址为0的Bipush指令:将整型推入操作数栈顶
    在这里插入图片描述
  3. 执行偏移地址为2的istore_1指令:将操作数栈顶的整型值出栈并存放到第一个局部变量槽中
    在这里插入图片描述
  4. iload_1和iload_2指令分别将局部变量表第1个和第二个变量槽中的整型值复制到操作数栈顶,iadd指令将操作数栈中头两个栈顶元素出栈,做整型加法, 然后把结果重新入栈

对象

HotSpot虚拟机对象探秘总结

  1. Java堆是否规整又由所采用 的垃圾收集器是否带有空间压缩整理(Compact)的能力决定选择空闲列表指针碰撞分配内存
  2. 保证内存分配原子性方式
    2.1 CAS配上失败重试的方式保证更新操作的原子性
    2.2 本地线程分配缓冲(Thread Local Allocation Buffer,TLAB):每个线程在Java堆中预先分配一小块内存
  3. 对象在堆内存中的存储布局可以划分为三个部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)
    3.1 对象头包含两类信息
    (1)Mark Word: 用于存储对象自身的运行时数据
    (2)类型指针:对象指向它的类型元数据的指针
  4. Java程序会通过栈上的reference数据来操作堆上的具体对象(对象的访问定位
    4.1 句柄访问:reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自具体的地址信息
    4.2 直接指针:reference中存储的直接就是对象地址

new指令源码分析总结

  1. 获取创建对象所属类地址(InstanceKlass),并将其入栈
  2. 尝试在TLAB区为对象分配内存,如果分配失败,会直接在Eden区进行分配
  3. 对象的初始化
    3.1 先初始化对象实例数据
    3.2 进行对象头的初始化

计算对象大小

  1. lucene提供的专门用于计算堆内存占用大小的工具类:RamUsageEstimator
    <dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-core</artifactId><version>4.0.0</version>
    </dependency>
    
  2. RamUsageEstimator就是根据java对象在堆内存中的存储格式,通过计算Java对象头、实例数据、引用等的大小,相加而得
  3. 常用方法如下:
    //计算指定对象及其引用树上的所有对象的综合大小,单位字节
    long RamUsageEstimator.sizeOf(Object obj)//计算指定对象本身在堆空间的大小,单位字节
    long RamUsageEstimator.shallowSizeOf(Object obj)//计算指定对象及其引用树上的所有对象的综合大小,返回可读的结果,如:2KB
    String RamUsageEstimator.humanSizeOf(Object obj)
    

束语

  虽然说没有debug Java虚拟机的能力,但在看相关书籍和文章前对自己提出相关问题,带着目的性去阅读还是能解答很多自己的内心的疑惑,后面继续沉淀吧

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

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

相关文章

期货开户止损是通向成功的保障

一、情绪波动止损法&#xff1a; 如果买入股票后&#xff0c;感觉不好&#xff0c;寝食难安&#xff0c;这说明自己认为买入理由不充分或信心不足&#xff0c;这将影响今后的正常操作&#xff0c;故应果断卖出离场。 二、空间位移止损法&#xff1a; 1、 初始止损法&#xf…

调用MapReuce对文件中各单词出现次数统计

调用MapReduce对文件中各单词出现次数统计 调用MapReuce对文件中各单词出现次数统计一、安装环境二、需求分析 1.创建hadoop账户2.设置Hadoop密码3.为Hadoop用户增加管理员权限4.更新apt5.安装vim6.安装SSH、配置SSH无密码登陆 三、安装java环境 1.安装JDK2.验证JDK安装情况3.…

SpringBoot 启用 GZIP 对响应进行压缩

SpringBoot Web 应用默认是不启用响应数据的压缩&#xff0c;对大的文本类型的响应数据进行压缩是十分必要的&#xff0c;如 JSON, XML 等应用数据&#xff0c;甚至是 JS, CSS 等。 早先的 Web 应用基本是要配置一个叫做 GzipFilter 之类的东西&#xff0c;然后判断请求的 Acc…

Windows与网络基础-1-2-虚拟机安装Windows10和window server2016

目录 一、虚拟机安装软件和ios镜像文件 二、新建虚拟机 2.1 文件—>新建虚拟机 2.2 选择典型安装 2.3 选择稍后安装 2.4 选择操作系统类型和版本 2.5 虚拟机名称和安装路径 2.6 指定磁盘大小 2.7 配置硬件信息 2.8 进入系统安装界面 2.9 选择系统版本 2.10 选择自…

LeetCode精选200道--二叉树篇(二)

二叉树篇&#xff08;二&#xff09;前言完全二叉树的节点个数普通二叉树逻辑递归完全二叉树逻辑平衡二叉树题外话递归二叉树的所有路径思路递归相同的树100. 相同的树另一棵树的子树左叶子之和思路找树左下角的值思路112. 路径总和思路106. 从中序与后序遍历序列构造二叉树根据…

FLASH:一种高效的Transformer设计

背景 近年来&#xff0c;Transformer凭借其优秀的设计&#xff0c;在文本、图像、语音等方向大杀四方。但是由于其attention的二次复杂度限制了其在长序列上的应用。本文提出了一种快(速度快)、省(省显存)的模型FLASH(Fast Linear Attention with a Single Head)&#xff0c;在…

SpringBoot 和 Vue前后端分离在线工具项目实战,源码+超详细讲解

一、前言 主要通过SpringBoot和Vue来实现一个前后端分离的在线工具平台&#xff0c;包含PDF转换、图片处理、文本处理、图表展示、二维码工具等功能。 为了更直观展示项目效果&#xff0c;也给大家提供了在线体验地址&#xff1a;http://49.234.28.149, 源码资源见文末。 通过…

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): 无效的绑定语句(未找到),就是写的sql 方法找不到sql。解决: 1 namespace 指向是否正确 路径与引用的方法的路径保持一致a.namespace 没有指向Dao b. id ,方法名没有对应上2 引用的方法…

记录Kettle连不上mysql8

如图所示&#xff0c;mysql升级到8了。 在很早之前&#xff0c;我一直用的是Mysql 5的驱动包去连接数据库&#xff0c;今天发现突然连接不上了&#xff0c;想了一下&#xff0c;应该是我以前升级mysql后的原因&#xff0c;换了mysql8的驱动后依旧没个卵用。 报错如下&#xff…

远程Debug远端服务器JVM配置

远程调试非本机的Java进程 远端Java进程启动的JVM参数 注意&#xff1a;以下配置尽量不要在线上生产环境开启&#xff0c;或者 JDK4: -Xdebug -Xrunjdwp:transportdt_socket,servery,suspendn,address{port} JDK5-JDK8: -agentlib:jdwptransportdt_socket,servery,suspen…

Python——LeetCode刷题——【383. 赎金信】

题目描述&#xff1a; 解题思路&#xff1a; 用字典记录字符串magazine中每个字符出现的次数。然后看看字典中magazine的各个字符的出现次数是否“够”字符串ransomNote中各个字符出现的次数。如果够&#xff0c;return True。如果存在有点字符不够&#xff0c;return False。…

学习:Python进阶 冒泡排序

#原理 列表每两个相邻的数,如果前面的数比后面的数大,则交换这两个数 一趟排序完成后,则无序曲减少一个数,有序区增加一个数 每循环一趟,从无序区冒出来一个最大的数,放入有序区,最终得到一个升序的列表

认真研究ConcurrentHashMap中的元素统计策略

这里我们想研究的是jdk1.8中ConcurrentHashMap的addCount(long x, int check)方法。如下所示在put方法的最后会触发addCount(long x, int check)方法进行元素个数的统计。 我们再回顾一下另一个参数binCount &#xff1a; 在操作链表的分支if (fh > 0)中 用于统计put前链表…

TinyRenderer学习笔记--Lesson 3、4

Lesson 3 zbuffer 无论怎样&#xff0c;生活中的显示器基本上都是平面&#xff0c;是一个2D的场景&#xff0c;而我们的模型却是3D的&#xff0c;是有深度的&#xff0c;实际上我们看见的都只是离我们的眼睛最近的那一个平面&#xff0c;一个不透明的3D物体的内部和背面是我们…

河北稳控科技使用标准信号检测 VM振弦采集模块测量精度

河北稳控科技使用标准信号检测 VM振弦采集模块测量精度(一) (1)电源1.1VDD 引脚电源必须使用 LDO 稳压或者低纹波线性电源, LDO 推荐使用 AM1117_3.3V 芯片,测试时发现 SPX 生产的 LDO会造成非常严重的干扰(其它品牌应该也会有类似的问题)。1.2VSEN 引脚电源单通道模块…

阿里、滴滴、华为等一线互联网分布式消息中间件:RocketMQ核心笔记

本篇介绍了RocketMQ的基本使用方法及其各个组件的基本原理&#xff0c;讲解原理时&#xff0c;都是采用先整体架构后详细分解的方式。详细分解时不会深入源码逐段讲&#xff0c;而是从代码结构出发梳理整个运行过程。 这份RocketMQ分布式消息中间件—核心原理与最佳实践的完整…

Android Studio应用基础,手把手教你从入门到精通(小白学习)总结2 之 常用界面布局和ListView

总结1链接&#xff1a; (156条消息) Android Studio应用基础&#xff0c;手把手教你从入门到精通&#xff08;小白学习&#xff09;总结1_好喜欢吃红柚子的博客-CSDN博客 学习视频链接&#xff1a; &#xff08;学完必会&#xff09;Android studio基础&#xff0c;从入门到…

尚好房 07_前端房源展示

尚好房&#xff1a;前端房源展示 一、分页显示房源列表 1、效果 2、项目搭建 2.1 创建项目 在web项目中创建子工程web-front 2.2 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0&…

stm32学习(二)|ADC电压采集DMA

利用ADC通道采集外部传感器数值,ADC通道选择依据实际查询芯片手册可得,相关配置利用Cubemx完成。 ADC参数配置首先选择需要使用的ADC通道,并设置对应的引脚ADC_IN0X.ADC参数设置(Paremeter setting)Mode : Independent mode,只使用一个ADC通道 Clock Prescaler,Resolut…

OpenGL 反色

目录 一.OpenGL 反色 1.IOS Object-C 版本2.Windows OpenGL ES 版本3.Windows OpenGL 版本 二.OpenGL 反色 GLSL Shader三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >&…