JVM剖析

0.前言

Java 是当今世界使用最广泛的技术平台之一。使用 Java 或 JVM 的一些技术包括:

  • Apache spark用于大数据处理,数据分析在JVM上运行;
  • 用于数据流的Apache NiFi在内部使用的也是 JVM;
  • 现代 Web 和移动应用程序开发中使用的React native使用 的也包含JVM 和 java 线程。

1.虚拟化

JVM 基于虚拟化技术(应用程序级虚拟化),它基本上是裸机硬件之上的抽象层。
传统计算机
虚拟化后的计算机
JVM 是应用程序级虚拟化的一个例子,它基本上是主机操作系统上的一个额外层。我们可以在操作系统内的沙箱中编译和运行 Java 程序,而不是直接使用操作系统例程。

2.代码编译与字节码

Java 代码在执行前要经过一系列转换。第一个编译过程从 java 编译器或javac开始,javac 将 java 代码转换为中间字节码,可以使用javap 等反汇编工具读取,字节码独立于计算机的平台架构,这是 java 编程语言具有可移植性的根本原因。

3.Java类结构

以下是使用 javap 反汇编后类文件的组成部分。

组成部分说明
魔数(Magic Number)0xCAFEBABE
类文件的版本(Magic Number)类文件的次要和主要版本
常量池(Constang Pool)类的常量池
访问标记(Access Flags)例如类是否为抽象、静态等等
当前类(This Class)当前类的名称
超类(Super Class)超类的名称
接口(Inrerfaces)类中所有的接口
方法(Methods)类中所有的方法

每个类文件都以一个魔法数字开头,用于确认给定文件是类文件,接下来是类格式的版本,用于检查 JVM 版本与用于编译类文件的版本的兼容性。如果存在任何不匹配,则会抛出UnsupportedClassVersionError 。

其他组件用于存储类中使用的常量,访问标志存储访问说明符(公共、私有、抽象等)。类似地,其他组件存储类中使用的超类名称、接口和方法。

public class HelloWorld { 
	public static void main(String[] args) { 
		for (int i = 0; i < 10; i++) {
			 System.out.println("Hello World");
	    } 
	}
}

反汇编上面的 hello world 程序,结果如下是运行 hello world 程序,结果如下:

Classfile /home/xxxxxxxx/Documents/learning/java/jvm/HelloWorld.class
  Last modified 7 Oct 2021; size 478 bytes
  SHA-256 checksum 93080c0483aa97ce4c226f31f22ed95c633e0da00b997fe229bfa676f6fb53c0
  Compiled from "HelloWorld.java"
public class HelloWorld
  minor version: 0
  major version: 52
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #5                          // HelloWorld
  super_class: #6                         // java/lang/Object
  interfaces: 0, fields: 0, methods: 2, attributes: 1

相应的机器语言指令将会是:

0: iconst_0
1: istore_1
2: iload_1
3: bipush        10
5: if_icmpge     22
8: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
11: ldc           #3                  // String Hello World
13: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
16: iinc          1, 1
19: goto          2
22: return

源码解读:将常量存储到JVM堆栈中加载并与10进行比较,如果数字大于或等于10,则停止并退出函数,否则打印“ Hello world ”,直到满足条件。

4.解释和类加载

JVM类加载
将给定的源代码转换为字节后,JVM 将开始逐行解释类文件。JVM 是基于堆栈的解释器机器,因此 JVM 将使用内部堆栈来存储执行结果,而不是使用CPU 寄存器。此过程从将执行所需的所有类加载到方法缓存中开始。

4.1.类加载

代码执行中的三个重要过程:

  • 加载:加载执行所需的所有类。

  • 链接:验证类文件并解析所有符号引用。

  • 初始化:初始化程序中定义的所有静态变量。

4.1.1.类加载器的类型

  • 启动类加载器: Bootstrap 类加载器将加载源代码中的所有核心类,包括包含 main 函数的类。

  • 扩展类加载器:扩展类加载器以引导类作为其父类加载器。如果核心 Java 类中的任何方法被重写,则扩展类加载器将加载该类而不是原始类。

  • 应用程序类加载器:加载类路径中找到的所有类。如果类路径中未找到某个类,则会抛出classnotfound异常。

5.热点编译

C++ 实现遵循零开销原则:您不用的东西就不用付费。而且,您用的东西,您编写的代码再好不过了。Bjarne Stroustrup

ava 是一种蓝领语言。它不是博士论文材料,而是一种工作语言。James Gosling

热点编译是一种使 Java 代码执行速度比 C 和 C++ 等语言更快、更高效的方法。热点编译是一种方法,在解释过程进行时,分析器将开始收集有关执行的信息,基于此信息,即时 ( JIT)编译器将应用一组优化。

6.Java内存分配及内存管理

JVM 中运行的所有线程都会有一个公共堆,运行程序所需的所有内存都会从这个堆中分配,如果所需内存大于当前 JVM 堆内存,则会引发内存超出范围的异常。默认情况下,对象是可变的,除非它们由 final 关键字定义。

一个线程创建的任何对象都可以被另一个线程访问,可以通过一种称为互斥锁或互斥锁的技术来避免异常情况(一个线程引用的内存被另一个线程改变)。

7.JIT编译

此过程也称为配置文件引导优化。配置文件将跟踪当前正在运行的子系统的信息,当值达到某个阈值时将应用一组优化。一些配置文件引导优化策略如下:

  • 基于计数器的优化: Profiler 将保留方法调用次数的计数。如果计数达到大于某个阈值的值,则将缓存该方法,下次无需再次解释该方法,而是直接从缓存中获取该值;
  • 堆栈上替换:缓存不经常使用但包含循环的方法;
  • 内联:例如,用更高效的代码替换的过程。

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

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

相关文章

nginx的缓存和gzip

nginx的缓存 缓存的基本思想是利用客户端访问的时间局限性&#xff0c;将客户端访问过的内容做一个副本&#xff0c;在一定时间内存放到本地&#xff0c;当改数据下次被访问时&#xff0c;不必连接到后端服务器反复去查询数据&#xff0c;而是由本地保存的副本响应数据。 保存…

node:ReferenceError: XMLHttpRequest is not defined

node&#xff1a;ReferenceError: XMLHttpRequest is not defined 1 前言 node执行如下代码&#xff1a; new XMLHttpRequest()报错提示&#xff1a;ReferenceError: XMLHttpRequest is not defined 2 解决 2.1 可能原因是没有安装xmlhttprequest npm install xmlhttpreq…

空格隔开的多个数据,可以用多个scanf()读取,也可以用一个scanf()读取

概要&#xff1a; 如果输入数据有多个&#xff0c;且用空格隔开 读取的时候&#xff0c;可以用多个scanf()读取 也可以用一个scanf()读取&#xff0c;在这个scanf()内部使用空格即可 一、用多个scanf()读取 1、代码 #include<stdio.h> int main() {int line[3];int…

window配置RUST开发环境详解

1.先安装VS2022: 下载 Visual Studio Tools - 免费安装 Windows、Mac、Linux (microsoft.com) 2.下载Rustup-init.exe Other Installation Methods - Rust Forge 3.运行rustup-init.exe开始安装rust开发环境: 安装成功出现下图所示 %USERPROFILE%\.cargo\bin 添加cargo安装路…

内网穿透时报错【Bad Request This combination of host and port requires TLS.】的原因

目录 前言&#xff1a;介绍一下内网穿透 1.内网直接https访问&#xff08;可以正常访问&#xff09; 程序配置的证书 2.内网穿透后,通过外网访问 3.原因 4.内网非https的Web应用&#xff0c;使用https后&#xff0c;也变成了https访问 5.题外话 感觉自己的web应用配置了…

155 Linux C++ 通讯架构实战10,工具telent 和 wireshark的使用

telnet工具使用介绍 windows 上开启telnet linux 上开始telnet 使用telnet //是一款命令行方式运行的客户端TCP通讯工具&#xff0c;可以连接到服务器端&#xff0c;往服务器端发送数据&#xff0c;也可以接收从服务器端发送过来的信息&#xff1b; //类似nginx5_1_1_clie…

3D检测:从pointnet,voxelnet,pointpillar到centerpoint

记录centerpoint学习笔记。目前被引用1275次&#xff0c;非常高。 地址&#xff1a;Center-Based 3D Object Detection and Tracking (thecvf.com) GitHub - tianweiy/CenterPoint CenterPoint&#xff1a;三维点云目标检测算法梳理及最新进展&#xff08;CVPR2021&#xff…

为 Linux 中的 Docker 配置阿里云和网易云国内镜像加速下载中心

由于默认情况下&#xff0c;Docker 的镜像下载中心默认为国外的镜像中心&#xff0c;使用该镜像中心拉去镜像会十分缓慢&#xff0c;所以我们需要配置国内的 Docker 镜像下载中心&#xff0c;加速 Docker 镜像的拉取。Docker 的国内镜像下载中心常用的有&#xff1a;阿里云、网…

精通Go语言文件上传:深入探讨r.FormFile函数的应用与优化

1. 介绍 1.1 概述 在 Web 开发中&#xff0c;文件上传是一项常见的功能需求&#xff0c;用于允许用户向服务器提交文件&#xff0c;如图像、文档、视频等。Go 语言作为一门强大的服务器端编程语言&#xff0c;提供了方便且高效的方式来处理文件上传操作。其中&#xff0c;r.F…

【EasyExcel】多sheet、追加列

业务-EasyExcel多sheet、追加列 背景 最近接到一个导出Excel的业务&#xff0c;需求就是多sheet&#xff0c;每个sheet导出不同结构&#xff0c;第一个sheet里面能够根据最后一列动态的追加列。原本使用的 pig4cloud 架子&#xff0c;使用 ResponseExcel注解方式组装返回数据…

手机无线投屏到windows11电脑

1 安装无线投影组件 2 电脑端打开允许其他设备投影的开关 3 手机找到投屏选项 4 手机搜索可用设备连接即可 这里的官方文档给的不太好,给了一些让人眼花撩乱的信息,以下是经过整合的有效信息

关系型数据库mysql(10)MHA的高可用

一. MHA 的相关知识 1. 什么是 MHA MHA&#xff08;MasterHigh Availability&#xff09;是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。MHA 的出现就是解决MySQL 单点的问题。MySQL故障切换过程中&#xff0c;MHA能做到0-30秒内自动完成故障切换操作。MHA能在故障…

《Java面试自救指南》(专题一)操作系统

文章目录 力推操作系统的三门神课操作系统的作用和功能线程、进程和协程的区别并行与并发的区别什么是文件描述符操作系统内核态和用户态的区别用户态切换到内核态的方式大内核和微内核的区别用户级线程和内核级线程的区别线程的七态模型进程调度算法有哪些进程间通信的七种方式…

鸿蒙实战开发-如何使用声明式UI编程框架的基础组件

介绍 在本教程中&#xff0c;我们将通过一个简单的样例&#xff0c;学习如何使用声明式UI编程框架的基础组件。本篇Codelab将会使用Image组件、Slider组件、Text组件共同实现一个可调节的风车动画&#xff0c;实现效果如图所示 相关概念 Text组件&#xff1a;文本组件&#x…

回收站删除以后还能撤销吗 回收站删除以后怎么找回 回收站清空了怎么恢复 easyrecovery数据恢复软件

回收站删除以后能撤销吗&#xff1f;有不少网友前一秒清空回收站&#xff0c;后一秒就开始在网上疯狂搜寻如何撤销删除回收站的办法。实际上&#xff0c;清空回收站并不可怕&#xff0c;被删除的数据仍然保存在我们的电脑硬盘中。今天我为大家介绍回收站删除以后怎么找回数据的…

数据可视化-Python

师从黑马程序员 Json的应用 Json的概念 Json的作用 Json格式数据转化 Python数据和Json数据的相互转化 注&#xff1a;把字典列表变为字符串用dumps,把字符串还原回字典或列表用loads import json#准备列表&#xff0c;列表内每一个元素都是字典&#xff0c;将其转化为Json …

HTTPS传输过程

HTTPS&#xff1a;超文本传输安全协议 相较于HTTP明文传输&#xff0c;HTTPS增加了SSL/TLS进行了加密增加了通信的安全性。 SSL和TLS是两个不同的加密方法&#xff0c;SSL是TLS的前身&#xff0c;现在绝大多数浏览器使用的是TLS&#xff0c;所以着重了解以下TLS的概念即可。 首…

算法——滑动窗口,按位或

先看最简单的&#xff1a;删除有序数组中的重复项 . - 力扣&#xff08;LeetCode&#xff09; 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该…

编曲知识11:吉他扫弦织体编写 基础贝斯编写 采样、小打编写

吉他扫弦织体编写 基础贝斯编写 采样、小打编写小鹅通-专注内容付费的技术服务商https://app8epdhy0u9502.pc.xiaoe-tech.com/live_pc/l_65f033afe4b092c16848e512?course_id=course_2XLKtQnQx9GrQHac7OPmHD9tqbv 吉他编写(二) 扫弦木吉他 扫弦模式开关:先点击点击红色箭…

你知道Linux线程池的重要性吗?带你手撕线程池

⭐小白苦学IT的博客主页 ⭐初学者必看&#xff1a;Linux操作系统入门 ⭐代码仓库&#xff1a;线程池实现源码 ❤关注我一起讨论和学习Linux系统 1.前言 你了解过Linux线程池吗&#xff1f;不了解&#xff1f;没有关系&#xff0c;先来带你了解一下我们的池化技术&#xff0c;以…