java虚拟机---JVM

JVM

JVM,也就是 Java 虚拟机,它最主要的作用就是对编译后的 Java 字节码文件逐行解释,翻译成机器码指令,并交给对应的操作系统去执行。
在这里插入图片描述
JVM 的其他特性有:

  • JVM 可以自动管理内存,通过垃圾回收器回收不再使用的对象并释放内存空间。
  • JVM 包含一个即时编译器 JIT,它可以在运行时将热点代码缓存到 codeCache 中,下次执行的时候不用再一行一行的解释,而是直接执行缓存后的机器码,执行效率会大幅提高。
    在这里插入图片描述
注:JIT 和 JNI 的区别:
JIT 是“即时编译”(Just-In-Time Compilation)的缩写。
它是一种在程序运行时将字节码(bytecode)编译成机器码的技术,主要用于提高程序的执行效率。JNI 是Java 提供的一种编程框架,允许 Java 代码与用其他语言(如 C、C++)编写的本地代码交互。
通过 JNI,Java 程序可以调用本地方法(native methods),这些方法通常是用 C 或 C++ 实现的,
并编译为动态链接库(DLL 或 SO 文件)。反过来,本地代码也可以调用 Java 方法
  • 任何可以通过 Java 编译的语言,比如说 Groovy、Kotlin、Scala 等,都可以在 JVM 上运行。
“通过 Java 编译”在问题中的含义是指“编译成 Java 字节码”,每种语言都有自己的专用编译器。

JVM的组织架构

JVM 要解释执行需要进行三个步骤:加载 .class 文件 -> 准备数据 -> 执行
因此 JVM 大致可以划分为三个部分:类加载器、运行时数据区和执行引擎

在这里插入图片描述

JVM内存模型

Java 虚拟机(JVM)在运行 Java 程序时,会将内存划分为若干区域,每个区域有其特定的功能。
在这里插入图片描述

  1. 程序计数器(Program Counter Register)

    • 作用:记录当前线程正在执行的字节码指令的地址,用于控制程序的执行流程。
    • 特点:每个线程都有独立的程序计数器,线程之间互不干扰。
  2. Java 虚拟机(Java Virtual Machine Stacks)

    • 作用:为 Java 方法(非 native 方法)的执行提供内存空间。
    • 特点:每个线程拥有自己的虚拟机栈,栈中包含多个栈帧(Stack Frame)。每个栈帧对应一次方法调用,存储局部变量表、操作数栈、动态链接和方法出口等信息。
  3. 本地方法栈(Native Method Stacks)

    • 作用:为 native 方法(用 C/C++ 等语言编写的方法)提供内存支持。
    • 特点:与 Java 虚拟机栈类似,但专用于 native 方法的执行。
  4. Java (Java Heap)

    • 作用:存储对象实例和数组。
    • 特点:JVM 中最大的内存区域,所有对象实例都在堆上分配内存。堆是垃圾收集器(GC)的主要管理区域。
  5. 方法区(Method Area)

    • 作用:存储类的元数据信息(如类结构)、静态变量、常量以及即时编译器编译后的代码。
    • 特点:在 JDK 8 及之后,方法区被元空间(Metaspace)取代,元空间使用本地内存而非 JVM 堆内存。
  6. 运行时常量池(Runtime Constant Pool)

    • 作用:存储编译期生成的字面量(如字符串常量)和符号引用。
    • 特点:是方法区的一部分,包含每个类的常量池表。JDK 8 方法区变元空间,运行时常量池就放在堆上。
  7. 直接内存(Direct Memory)

    • 作用:不属于 JVM 运行时数据区,但常用于 NIO(如 ByteBuffer)等场景。
    • 特点:使用本地内存,不受 JVM 堆大小限制。

内存区域变化

在这里插入图片描述
主要是方法区到元空间,以及常量池的变化

字符串常量池,类常量池,运行时常量池存储的都是什么啊?

1.字符串常量池
  • 字符串常量池主要存储 字符串字面量,也就是在 Java 代码中用双引号括起来的字符串,例如 “Hello”、“World” 等。
  • 它的设计目的是为了复用这些字符串对象,确保 JVM 中每个唯一的字符串字面量只有一份,从而节省内存。
  • String s1 = “Hello”; String s2 = “Hello”;用 s1 == s2 验证,结果为 true
  • 用 new String(“Hello”) 创建字符串,这个对象会分配在堆上,可以通过 String.intern() 方法将它放入字符串常量池。
2.类常量池
  • javac 将源文件编译成 .class 文件,类常量池指的是这个文件的一部分,是在磁盘上的
  • 类常量池存储了在编译时生成的 字面量符号引用
  • 类加载阶段JVM 加载 .class 文件 时,会把类常量池的内容 拷贝到方法区(JDK 8+ 在元空间)
  • 在解析阶段,逻辑地址会被替换为 实际的内存地址,部分数据进入 运行时常量池。

例如对于一个类:

package example;import utils.Helper;  // 🔹 导入外部类public class Main {// 🔹 静态常量static final double PI = 3.14159;// 🔹 实例变量private String name;// 🔹 构造方法public Main(String name) {this.name = name;}// 🔹 普通方法public void greet() {System.out.println("Hello, " + name);}public static void main(String[] args) {// 🔹 创建对象Main obj = new Main("Alice");obj.greet();// 🔹 调用外部类方法Helper.sayHello();}
}

类常量池为:

CONSTANT_Class      example/Main
CONSTANT_Class      utils/Helper  // 🔹 外部类
CONSTANT_Fieldref   example/Main.PI
CONSTANT_Fieldref   example/Main.name
CONSTANT_Methodref  example/Main.<init>  // 🔹 构造方法
CONSTANT_Methodref  example/Main.greet   // 🔹 方法
CONSTANT_Methodref  utils/Helper.sayHello  // 🔹 外部类方法
CONSTANT_String     "Hello, "
CONSTANT_String     "Alice"
CONSTANT_Double     3.14159
3.运行时常量池
  • 运行时常量池是 JVM 在运行时为每个类或接口维护的常量池
  • 运行时常量池支持动态链接和运行时解析,例如将对 System.out.println 的符号引用解析为具体的对象和方法地址
  • 它还能在程序运行时扩展,例如添加新的字符串常量
  • 运行时常量池 = 类常量池内容 + 直接引用 + 动态常量

堆内存

堆 是Java虚拟机(JVM)中内存管理的一个重要区域,主要用于存放对象实例和数组。随着JVM的发展和不同垃圾收集器的实现,堆的具体划分可能会有所不同,但通常可以分为以下几个部分:
在这里插入图片描述

  • 新生代:新生代又被划分为 Eden 空间和两个 Survivor 空间(From 和 To)
    • 新创建的对象会被分配到 Eden 空间。
    • Eden 区填满时,会触发一次 Minor GC,清除不再使用的对象。存活下来的对象会从 Eden 区移动到 Survivor 区
  • 老年代:对象在新生代中经历多次 GC 后,如果仍然存活,会被移动到老年代。当老年代内存不足时,会触发 Major GC,对整个堆进行垃圾回收。
  • 大对象区:在某些JVM实现中(如G1垃圾收集器),为大对象分配了专门的区域,这部分区域在老年代。

对象的内存布局

对象的内存布局是由 Java 虚拟机规范定义的,但具体的实现细节各有不同,如 HotSpot 和 OpenJ9 就不一样。HotSpot:
在这里插入图片描述

对象四种引用

四种分别是“强、软、弱、虚”
在这里插入图片描述

  • 强引用:Object obj = new Object(); 只要存在就不回收;
  • 软引用:SoftReference softRef = new SoftReference<>(new Object()); 内存不足回收,常用于实现内存敏感的缓存(如图片缓存),在内存压力大时自动清理;
  • 弱引用:WeakReference weakRef = new WeakReference<>(new Object()); 一定回收,临时引用,避免内存占用,比如 threadlocal 里的 key;
  • 虚引用:PhantomReference phantomRef = new PhantomReference<>(new Object(), queue); 通常与 ReferenceQueue 结合使用,当对象被回收时,虚引用会被放入关联的 ReferenceQueue,在对象被回收时收到通知。虚引用不可达;
  • Java.lang.ref 包下的类

内存泄漏和内存溢出

用一个比较有味道的比喻来形容就是,内存溢出是排队去蹲坑,发现没坑了;内存泄漏,就是有人占着茅坑不拉屎,导致坑位不够用。
在这里插入图片描述

  • 内存泄漏举例:1、静态属性导致内存泄露 2、 未关闭的资源 3、 使用ThreadLocal
  • 静态属性(用 static 修饰的字段)属于类级别,其生命周期与类的加载和卸载绑定,其超长的生命周期和全局可见性导致更容易内存泄漏
    ThreadLocal—java

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

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

相关文章

VectorBT:使用PyTorch+LSTM训练和回测股票模型 进阶四

VectorBT&#xff1a;使用PyTorchLSTM训练和回测股票模型 进阶四 本方案融合 LSTM 时序预测与动态风险控制。系统采用混合架构&#xff0c;离线训练构建多尺度特征工程和双均线策略&#xff0c;结合在线增量更新持续优化模型。技术要点包括三层特征筛选、波动率动态仓位管理、混…

前端中rem,vh,vw

1. rem&#xff08;Root EM&#xff09; 参照对象 基准&#xff1a;相对于 根元素&#xff08;<html>&#xff09;的 font-size 计算。 默认情况下&#xff0c;浏览器的根 font-size 为 16px&#xff08;即 1rem 16px&#xff09;&#xff0c;但可通过 CSS 修改&#…

详解 MySQL 常见的存储引擎及它们之间的区别

MySQL 支持多种存储引擎&#xff0c;每种引擎针对不同的应用场景提供了特定的特性和优化。下面是几种常见的存储引擎以及它们之间的主要区别&#xff1a; 常见存储引擎 1. InnoDB&#xff08;重点&#xff09; 事务支持&#xff1a; 完全支持 ACID 事务&#xff0c;确保数据一…

html+css+js 实现一个贪吃蛇小游戏

目录 游戏简介 游戏功能与特点 如何玩转贪吃蛇 游戏设计与实现 HTML结构 JavaScript核心实现 代码结构&#xff1a; 效果 关于“其他游戏” 游戏简介 贪吃蛇是一款经典的单人小游戏&#xff0c;玩家通过控制蛇的移动&#xff0c;吃掉食物来增加长度&#xff0c;避免撞…

GLSL(OpenGL 着色器语言)基础语法

GLSL&#xff08;OpenGL 着色器语言&#xff09;基础语法 GLSL&#xff08;OpenGL Shading Language&#xff09;是 OpenGL 计算着色器的语言&#xff0c;语法类似于 C 语言&#xff0c;但提供了针对 GPU 的特殊功能&#xff0c;如向量运算和矩阵运算。 着色器的开头总是要声明…

ngx_http_core_merge_srv_conf

定义在 src\http\ngx_http_core_module.c static char * ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) {ngx_http_core_srv_conf_t *prev parent;ngx_http_core_srv_conf_t *conf child;ngx_str_t name;ngx_http_server_name_t…

uni-app:firstUI框架的选择器Select改造,添加一个搜索的插槽

<fui-select :show"showSiteType" :options"siteTypeList" textKey"dict_label" title"请选择站点类型" confirm"chooseSiteType" close"onCloseSiteType"><template v-slot:search><view><…

Debian/Ubuntu的networking的`/etc/network/interfaces`配置文件,如何配置route路由

Debian/Ubuntu的networking的/etc/network/interfaces配置文件,如何配置route路由 在 Debian/Ubuntu 系统中&#xff0c;通过 /etc/network/interfaces 配置文件配置路由&#xff08;静态路由或默认路由&#xff09;可以通过以下方式实现。以下是详细配置方法及示例&#xff1…

天梯赛 L2-024 部落

一个并查集题目&#xff0c;难点就在于统计总人数&#xff0c;使用map即可&#xff0c;还有需要注意的是编号不一定是小于N的&#xff0c;小于10000的&#xff0c;需要注意。 #include<bits/stdc.h> using namespace std; const int N 10010; int fa[N]; int find(int …

uniapp 微信小程序 使用ucharts

文章目录 前言一、组件功能概述二、代码结构分析2.1 模板结构 总结 前言 本文介绍一个基于 Vue 框架的小程序图表组件开发方案。该组件通过 uCharts 库实现折线图的绘制&#xff0c;并支持滚动、缩放、触摸提示等交互功能。文章将从代码结构、核心方法、交互实现和样式设计等方…

Axure项目实战:智慧运输平台后台管理端-承运商管理(中继器筛选)

亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! 课程主题:智慧运输平台后台管理端 主要内容:承运商管理 应用场景:条件筛选、增删改查操作、台账制作 案例展示: 正文内容: 承运商管理模块主要解决平台对承运商的管理,包括新增承运商作,审核承运商申请,修…

[论文笔记] Deepseek技术报告解读: MLAMTP

1. RMSNorm 归一化层 class RMSNorm(nn.Module):def __init__(self, dim: int, eps: float = 1e-8):super().__init__()self.eps = epsself.weight = nn.Parameter(torch.ones(dim)) # 可学习的缩放参数def _norm(self, x: torch.Tensor):return x * torch.rsqrt(x.pow(2).me…

八款内网电脑监控软件:探寻适配企业需求的数字化监管方案组合

数字化办公的时代背景下&#xff0c;企业管理面临着前所未有的挑战。如何实现对员工办公行为的高效管理&#xff0c;确保网络资源的合理利用&#xff0c;成为众多企业决策者和高级管理人员亟待解决的重要问题。内网电脑监控软件作为一种有效的管理工具&#xff0c;应运而生。本…

Flutter求助贴

报错信息&#xff1a;The Dart VM Service was not discovered after 30 seconds. This is taking much longer than expected... 基本情况&#xff1a; 硬件&#xff1a;mac(15.3.1)&#xff0c;iPad(iOS 16.6),iPhone 16 pro(iOS 18.4) 项目环境 flutter&#xff1a;3.16…

React(九)React Hooks

初识Hook 我们到底为什么需要hook那? 函数组件类组件存在问题 函数组件存在的问题&#xff1a; import React, { PureComponent } from reactfunction HelloWorld2(props) {let message"Hello world"// 函数式组件存在的缺陷&#xff1a;// 1.修改message之后&a…

数据清洗的具体内容

&#xff08;一&#xff09;ETL介绍 “ETL&#xff0c;是英文Extract-Transform-Load的缩写&#xff0c;用来描述将数据从来源端经过抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;、加载&#xff08;Load&#xff09;至目的端的过程。ETL一词较…

【动手学深度学习】#7 现代卷积神经网络

主要参考学习资料&#xff1a; 《动手学深度学习》阿斯顿张 等 著 【动手学深度学习 PyTorch版】哔哩哔哩跟李牧学AI 概述 硬件性能和大数据的发展为深度卷积神经网络&#xff08;AlexNet&#xff09;的实现提供了条件。VGG首次将块的思想用于搭建网络。NiN将多层感知机应用在…

Jenkins + CICD流程一键自动部署Vue前端项目(保姆级)

git仓库地址&#xff1a;参考以下代码完成,或者采用自己的代码。 南泽/cicd-test 拉取项目代码到本地 使用云服务器或虚拟机采用docker部署jenkins 安装docker过程省略 采用docker部署jenkins&#xff0c;注意这里的命令&#xff0c;一定要映射docker路径&#xff0c;否则无…

使用 libevent 处理 TCP 粘包问题(基于 Content-Length 或双 \r\n)

在基于 libevent 的 TCP 服务器开发中,处理消息边界是常见需求。以下是两种主流分包方案的完整实现: 一、基于 Content-Length 的分包方案 1.1 数据结构设计 typedef struct {struct bufferevent *bev;int content_length; // 当前消息的预期长度int received_bytes; //…

酶动力学预测工具CataPro安装教程

简介&#xff1a;预测酶动力学参数是酶发现和酶工程中的一项重要任务。在此&#xff0c;研究人员基于蛋白质语言模型、小分子语言模型和分子指纹&#xff0c;提出了一种名为 CataPro 的新酶动力学参数预测算法。该研究从 BRENDA 和 SABIO-RK 数据库中收集了最新的转化率&#x…