【JVM】JVM执行流程和内存区域划分
文章目录
- 是什么
- JVM 执行流程
- 内存区域划分
- 堆
- 栈
- 程序计数器
- 元数据区
- 经典笔试题
是什么
Java 虚拟机
- JDK,Java 开发工具包
- JRE,Java 运行时环境
- JVM,Java 虚拟机
JVM 就是 Java 虚拟机,解释执行 Java 字节码
JVM 执行流程
编程语言可以分为:
- 编译型语言:先将高级语言转换成二进制的机器指令,再由 CPU 去直接执行
- 解释型语言:一边去转换,一边去执行
这样的说法放单今天,硬件不适用了
按照上述这种经典的划分方式,可以认为 Java 属于“半编译,半解释”。Java 这么设定,最主要的目的就是为了“跨平台”。
- 像 C++这样的语言是直接编译成了二进制的机器指令,而不同的
CPU支持的指令不一样,而且生成的可执行程序,在不同的系统上也有不同的格式Windows可执行程序:PE格式Linux可执行程序:ELF格式
当前看到的手机操作系统,为什么只有安卓、iOS?
- 因为搞一个新的系统,现有的软件不能兼容,没有生态也就没有市场
- 鸿蒙能直接运行安卓程序,是因为鸿蒙不是新系统,只是安卓套壳
Java 不想重新编译,而是期望能够直接执行
- 先通过
javac把.java文件==>.class文件(字节码文件,包含的就是Java字节码,Java自己搞的一套CPU指令)- 因为如果生成
CPU直接能执行的指令的话,不同的CPU支持的指令就不一样,就不能在所有系统上执行
- 因为如果生成
- 这样先把
java代码转成对应的java字节码文件,然后在某个具体的系统平台上执行,此时通过JVM把上述的字节码转换成对应的CPU能识别的机器指令(JVM就是一个翻译官的角色)
通过上述转换,我们就可以不去重新编译,也能够完成良好的跨平台。因此,我们编写和发布一个 java 程序,其实就只要发布 .class 文件就可以了,JVM 拿到 .class 文件之后,就知道如何转换
Windows上的JVM就可以把.class转换成Windows上能支持的可执行指令了Linux上的JVM就可以把.class转换成 Linux 上可以支持的可执行指令了
不同平台的局面是存在差异的,而不是同一个。对上(给java层面上提供的内容)是统一一致的
内存区域划分
JVM 其实也是一个进程(任务管理器中看到的 java 进程)
进程运行过程中,要从操作系统这里车身轻一些资源(内存就是其中的典型资源),这些内存空间就支撑了后续 java 程序的执行。
- 比如,在
java中定义变量(就会申请内存),内存其实就是JVM从系统这边申请到的内存,然后再交给具体的java程序去使用
JVM 从系统申请了一大块内存,这一大块内存给 java 程序使用的时候,又会根据实际的使用用途,来划分出不同的空间,这就是所谓的“区域划分”
堆
代码中 new 出来的对象,都是在堆里。对象中持有的非静态成员变量,也都在堆里。只有一份
- 静态成员变量在元数据区
栈
本地方法栈/虚拟机栈。包含了方法调用关系和局部变量
- 在代码执行过程中,肯定会涉及到很多方法的调用,调用的关系就通过栈空间记录下来
- 虚拟机栈,记录了
Java代码的调用关系,Java代码的局部变量 - 本地方法栈,记录了
JVM内部,通过C++写的代码的调用关系和局部变量
一般不会关注本地方法栈,一般来说谈到栈,就默认指的是“虚拟机栈”
这里谈到的“堆“和“栈“,和数据结构中的“堆“和“栈“是不同的。这里的是两块区域
程序计数器
这个区域比较小,专门用来存储下一条要执行的 Java 指令的地址
元数据区
“元数据”是计算机中的一个常见术语(meta data),往往指的是一些辅助性质的,描述性质的属性。只有一份
比如:硬盘上不仅仅要存储数据本体,还要存储一些辅助信息:文件的大小、文件的位置、文件的拥有者、文件的修改时间、文件的权限信息… 这些辅助信息统称为“元数据”
在以前的 Java 版本中,也叫做“方法区”,从 1.8 开始改的名字
云数据区中主要保存:
- 类的信息
- 方法的信息
一个程序,有哪些类、每个类里都有哪些方法、每个方法里面都要包含哪些指令,都会记录在元数据区。
我们写的 Java 代码,if、while、for 等各种逻辑运算,这些操作都会被转换成 Java 字节码
javac就会完成上述代码到字节码的转换- 此时这些字节码在程序运行的时候就会被
JVM加载到内存中,放到元数据区(方法区)里面 - 之后,当前程序要如何执行,要做哪些事情,就会按照上述元数据区里面记录的字节码一次执行了
我们所编写的代码,都会被转换成二进制指令,都会进入到内存中,然后才能执行。
类似于剧本杀
- 剧本杀里面给美格玩家发一个剧本,每个玩家就按照剧本上给出的要求来演
- 此处所谓 Java 字节码,要执行的方法的细节,就像剧本一样,需要把剧本加载到内存中,然后才能执行
堆和元数据区只有一份(所有线程共享一份),栈和程序计数器可能有 n 份(和线程相关,每个线程都有自己的程序计数器和栈(每个线程有自己的执行流))
经典笔试题
在下面代码中,t、n、m 分别处于 JVM 内存中的哪个区域?
class Test() {private int n;private static int m;
}main() {Test t = new Text();
}
t是一个局部变量(引用类型),在栈上n是Test的成员变量,new出来的Test是在堆上的,所以n作为成员变量也是处于堆上static修饰的变量,称为“类属性”;static修饰的方法,称为“类方法”- 非
static修饰的变量,称为“实例属性”;非static修饰的方法,称为“实例方法” - 所以这里的
m是长在类上的成员,和new不new实例没有关系。上述带有static修饰的变量,就是在类对象中,也就是在元数据区中(方法区)
类对象,
Test.class
JVM把.class文件加载到内存之后,就会把这里的信息使用对象来表示,此时这样的对象就是类对象- 类对象里就包含了一系列的信息,包括但不限于:
- 类的名称
- 类继承自那个类
- 实现了哪些接口
- 都有哪些成员,都叫什么,都是什么类型,都是什么权限
- 都有哪些方法,都叫什么,都是什么参数,都是什么权限
.java文件中涉及到的信息都会在.class中有所体现(注释是不会包含的)
区分一个变量在哪个内存区域中,最主要的就是看变量的形态
- 局部变量
- 成员变量
- 静态成员变量
- …
相关文章:
【JVM】JVM执行流程和内存区域划分
文章目录 是什么JVM 执行流程内存区域划分堆栈程序计数器元数据区经典笔试题 是什么 Java 虚拟机 JDK,Java 开发工具包JRE,Java 运行时环境JVM,Java 虚拟机 JVM 就是 Java 虚拟机,解释执行 Java 字节码 JVM 执行流程 编程语言…...
Python | 读取.dat 文件
写在前面 使用matlab可以输出为 .dat 或者 .mat 形式的文件,之前介绍过读取 .mat 后缀文件,今天正好把 .dat 的读取也记录一下。 读取方法 这里可以使用pandas库将其作为一个dataframe的形式读取进python,数据内容格式如下,根据…...
信息技术的变革与未来发展的思考
信息技术的变革与未来发展的思考 在21世纪,信息技术(IT)正在以前所未有的速度推动社会、经济、文化的深刻变革。无论是人工智能、大数据,还是云计算、物联网,信息技术的发展已经渗透到了各个行业,彻底改变…...
融会贯通记单词,绝对丝滑,一天轻松记几百
如果我将flower(花)、flat(公寓)、floor(地板)、plane(飞机)几个单词放在一起,你会怎么来记忆这样的一些单词呢? 我们会发现,我们首先可以将plane去掉,因为它看上去几乎就是一个异类。这样,我们首先就可以将…...
【计算机视觉】YoloV8-训练与测试教程
✨ Blog’s 主页: 白乐天_ξ( ✿>◡❛) 🌈 个人Motto:他强任他强,清风拂山冈! 💫 欢迎来到我的学习笔记! 制作数据集 Labelme 数据集 数据集选用自己标注的,可参考以下:…...
响应式布局-媒体查询父级布局容器
1.响应式布局容器 父局作为布局容器,配合自己元素实现变化效果,原理:在不通过屏幕下面吗,通过媒体查询来改变子元素的排列方式和大小,从而实现不同尺寸屏幕下看到不同的效果。 2.响应尺寸布局容器常见宽度划分 手机-…...
Android APN type 配置和问题
问题/疑问 如果APN配置了非法类型(代码没有定义的),则APN匹配加载的时候最终结果会是空类型。 那么到底是xml解析到数据库就是空type呢?还是Java代码匹配的时候映射是空的呢? Debug Log 尝试将原本的APN type加入ota或者新建一条ota type APN,检查log情况。 //Type有…...
前端mock了所有……
目录 一、背景描述 二、开发流程 1.引入Mock 2.创建文件 3.需求描述 4.Mock实现 三、总结 一、背景描述 前提: 事情是这样的,老板想要我们写一个demo拿去路演/拉项目,有一些数据,希望前端接一下,写几个表格&a…...
fiddler抓包10_列表显示请求方法
① 请求列表表头,鼠标悬停点击右键弹出选项菜单。 ② 点击“Customize columns”(定制列)。 ③ 弹窗中,“Collection”下拉列表选择“Miscellaneous”(更多字段)。 ④ “Field Name”选择“RequestMethod”…...
Win10系统复制、粘贴、新建、删除文件或文件夹后需要手动刷新的解决办法
有些win10系统可能会出现新建、粘贴、删除文件或文件夹后保持原来的状态不变,需要手动刷新,我这边新装的几个系统都有这个问题,已经困扰很久了,我从微软论坛和CSDN社区找了了很多方法都没解决,微软工程师给的建议包括重…...
BERT训练环节(代码实现)
1.代码实现 #导包 import torch from torch import nn import dltools #加载数据需要用到的声明变量 batch_size, max_len 1, 64 #获取训练数据迭代器、词汇表 train_iter, vocab dltools.load_data_wiki(batch_size, max_len) #其余都是二维数组 #tokens, segments, vali…...
必须执行该语句才能获得结果
UncategorizedSQLException: Error getting generated key or setting result to parameter object. Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 必须执行该语句才能获得结果。 ; uncategorized SQLException; SQL state [null]; error code [0]; 必须执行该语句…...
AI论文写作可靠吗?分享5款论文写作助手ai免费网站
AI论文写作的可靠性是一个备受关注的话题。在当前的技术背景下,AI写作工具能够显著提高论文写作的效率和质量,但其可靠性和安全性仍需谨慎评估。 AI论文写作的可靠性 技术能力与限制 AI论文写作的质量很大程度上取决于用户提供的输入指令或素材的质量…...
AJAX 入门 day3 XMLHttpRequest、Promise对象、自己封装简单版的axios
目录 1.XMLHttpRequest 1.1 XMLHttpRequest认识 1.2 用ajax发送请求 1.3 案例 1.4 XMLHttpRequest - 查询参数 1.5 XMLHttpRequest - 数据提交 2.Promise 2.1 Promise认识 2.2 Promise - 三种状态 2.3 案例 3.封装简易版 axios 3.1 封装_简易axios_获取省份列表 3…...
oracle avg、count、max、min、sum、having、any、all、nvl的用法
组函数 having的使用 any的使用 all的使用 nvl 从执行结果来看,nvl(列名,默认值),nvl的作用就是如果列名所在的这一行出现空则用默认值替换...
Python一分钟:装饰器
一、装饰器基础 函数即对象 在python中函数可以作为参数传递,和任何其它对象一样如:str、int、float、list等等 def say_hello(name):return f"Hello {name}"def be_awesome(name):return f"Yo {name}, together were the awesomest!"def gr…...
Docker部署ddns-go教程(包含完整的配置过程)
本章教程教程,主要介绍如何用Docker部署ddns-go。 一、拉取容器 docker pull jeessy/ddns-go:v6.7.0二、运行容器 docker run -d \--name ddns-go \--restart unless-stopped \...
简单多状态dp第三弹 leetcode -买卖股票的最佳时机问题
309. 买卖股票的最佳时机含冷冻期 买卖股票的最佳时机含冷冻期 分析: 使用动态规划解决 状态表示: 由于有「买入」「可交易」「冷冻期」三个状态,因此我们可以选择用三个数组,其中: ▪ dp[i][0] 表示:第 i 天结束后,…...
游戏化在电子课程中的作用:提高参与度和学习成果
游戏化,即游戏设计元素在非游戏环境中的应用,已成为电子学习领域的强大工具。通过将积分、徽章、排行榜和挑战等游戏机制整合到教育内容中,电子课程可以变得更具吸引力、激励性和有效性。以下是游戏化如何在转变电子学习中发挥重要作用&#…...
php+mysql安装
1.卸载mysql 没启动不停止 2.下载 3.解压 4.点击安装 5.出现成功 端口占用修改 修改端口89或者87 可视化扩展 修改后重启 开启扩展...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
Sklearn 机器学习 缺失值处理 获取填充失值的统计值
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...
阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)
cd /home 进入home盘 安装虚拟环境: 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境: virtualenv myenv 3、激活虚拟环境(激活环境可以在当前环境下安装包) source myenv/bin/activate 此时,终端…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...
