java虚拟机---JVM

news2025/4/8 6:05:03

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.coloradmin.cn/o/2330252.html

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

相关文章

2025数字中国初赛wp

一&#xff0c;取证与溯源 镜像文件解压密码&#xff1a;44216bed0e6960fa 1.运维人员误删除了一个重要的word文件&#xff0c;请通过数据恢复手段恢复该文件&#xff0c;文件内容即为答案。 先用R-stuido软件进行数据恢复 得到 打开重要文件.docx全选发现有一条空白的被选中…

c#和c++脚本解释器科学运算

说明&#xff1a; 我希望用c#和c写一个脚本解释器&#xff0c;用于科学运算 效果图&#xff1a; step1: c# C:\Users\wangrusheng\RiderProjects\WinFormsApp3\WinFormsApp3\Form1.cs using System; using System.Collections.Generic; using System.Data; using System.Tex…

青蛙吃虫--dp

1.dp数组有关元素--路长和次数 2.递推公式 3.遍历顺序--最终影响的是路长&#xff0c;在外面 其次次数遍历&#xff0c;即这次路长所有情况都更新 最后&#xff0c;遍历次数自然就要遍历跳长 4.max时时更新 dp版本 #include<bits/stdc.h> using namespace std; #def…

LINUX 5 cat du head tail wc 计算机拓扑结构 计算机网络 服务器 计算机硬件

计算机网络 计算机拓扑结构 计算机按性能指标分&#xff1a;巨型机、大型机、小型机、微型机。大型机、小型机安全稳定&#xff0c;小型机用于邮件服务器 Unix系统。按用途分&#xff1a;专用机、通用机 计算机网络&#xff1a;局域网‘、广域网 通信协议’ 计算机终端、客户端…

ModuleNotFoundError: No module named ‘pandas‘

在使用Python绘制散点图表的时候&#xff0c;运行程序报错&#xff0c;如图&#xff1a; 报错显示Python 环境中可能没有安装 pandas 库&#xff0c;执行pip list命令查看&#xff0c;果然没有安装pandas 库&#xff0c;如图&#xff1a; 执行命令&#xff1a;python -m pip in…

【教程】MacBook 安装 VSCode 并连接远程服务器

目录 需求步骤问题处理 需求 在 Mac 上安装 VSCode&#xff0c;并连接跳板机和服务器。 步骤 Step1&#xff1a;从VSCode官网&#xff08;https://code.visualstudio.com/download&#xff09;下载安装包&#xff1a; Step2&#xff1a;下载完成之后&#xff0c;直接双击就能…

Unet网络的Pytorch实现和matlab实现

文章目录 一、Unet网络简介1.1 输入图像1.2 编码器部分&#xff08;Contracting Path&#xff09;1.3 解码器部分&#xff08;Expanding Path&#xff09;1.4 最后一层&#xff08;输出&#xff09;1.5 跳跃连接&#xff08;Skip Connections&#xff09; 二、Unet网络的Pytorc…

【合新通信】相控阵雷达RFoF方案的应用

一、相控阵雷达为何需要RFoF&#xff1f; 核心需求驱动 分布式部署&#xff1a;相控阵雷达&#xff08;AESA/PESA&#xff09;的T/R模块需分散布局&#xff08;如舰载雷达阵面、卫星载荷&#xff09;&#xff0c;传统同轴电缆导致重量和损耗剧增。高频段挑战&#xff1a;X/Ku/…

原理图输出网表及调入

一、输出网表操作步骤 &#xff08;1&#xff09;选中.dsn文件&#xff0c;选者N或进入tools下拉列表选择Creat Netlists &#xff08;2&#xff09;导出网表后的文件 二、网表的导入 &#xff08;1&#xff09;执行菜单命令“File-Import-Logic/netlist”&#xff0c;将原理…

TDengine JAVA 语言连接器

简介 本节简介 TDengine 最重要且使用最多的连接器, 本节内容是以教科书式方式列出对外提供的接口及功能及使用过程中要注意的技术细节&#xff0c;大家可以收藏起来做为今后开发 TDengine 的参考资料。 taos-jdbcdriver 是 TDengine 的官方 Java 语言连接器&#xff0c;Java…

【NLP 55、实践 ⑬ LoRA完成NER任务】

目录 一、数据文件 二、模型配置文件 config.py 三、数据加载文件 loader.py 1.导入文件和类的定义 2.初始化 3.数据加载方法 代码运行流程 4.文本编码 / 解码方法    ① encode_sentence()&#xff1a; ② decode()&#xff1a; 代码运行流程 ③ padding()&#xff1a; 代码…

【蓝桥杯】Python大学A组第十五届省赛

1.填空题 1.1.拼正方形 问题描述 小蓝正在玩拼图游戏,他有个的方块和个的方块,他需要从中挑出一些来拼出一个正方形。 比如用个和个的方块可以拼出一个的正方形;用个的方块可以拼出一个的正方形。 请问小蓝能拼成的最大的正方形的边长为多少。 import math # 2*2的个数 a =…

小球反弹(蓝桥杯C语言)

有一长方形&#xff0c;长为 343720343720 单位长度&#xff0c;宽为 233333233333 单位长度。在其内部左上角顶点有一小球 (无视其体积)&#xff0c;其初速度如图所示且保持运动速率不变&#xff0c;分解到长宽两个方向上的速率之比为 dx:dy15:17dx:dy15:17。小球碰到长方形的…

HarmonyOS-ArkUI Ability进阶系列-UIAbility与各类Context

UIAbility及相关类关系 一个模块编译的时候会出一个HAP包&#xff0c; 每一个HAP包在运行时都对应一个AbilityStage。 AbilityStage持有一个AbilityStageContext一个APP&#xff0c; 有时候会有很多个HAP包&#xff0c; 至少一个。 一个APP运行时&#xff0c;对应的是我们的App…

剑指Offer(数据结构与算法面试题精讲)C++版——day4

剑指Offer&#xff08;数据结构与算法面试题精讲&#xff09;C版——day4 题目一&#xff1a;和为k的子数组题目二&#xff1a;0和1个数相同的子数组题目三&#xff1a;左右两边子数组的和相等 题目一&#xff1a;和为k的子数组 结合前面着重阐述的双指针法这一经典的算法技巧&…

WebRTC技术简介及应用场景

写在前面 本文是参考稀土掘金的文章,整理得出,版权归原作者所有!参考链接请点击跳转 WebRTC&#xff08;Web Real-Time Communication&#xff09; 是一项开源技术&#xff0c;允许浏览器和移动应用直接进行实时音视频通信和数据传输&#xff0c;无需安装插件或第三方软件。它…

介绍几种创意登录页(含完整源码)

今天为大家收集了几种不同风格的登录页&#xff0c;搭配动态渐变背景&#xff0c;效果绝对惊艳&#xff01; CSS3实现动态渐变玻璃拟态登录页 一、开篇语 纯CSS实现当下最火的玻璃拟态(Morphism)风格登录页&#xff0c;搭配动态渐变背景&#xff0c;效果绝对惊艳&#xff01; …

Uni-app入门到精通:uni-app的基础组件

1、view view是容器组件&#xff0c;类似于HTML中的<div></div>标签&#xff0c;用于包裹各种元素内容&#xff0c;是页面布局常用的组件。view组件的属性如下 属性类型默认值说明hover-classStringnone指定按下去的样式类。当hover-class"none"时&…

大文件上传源码,支持单个大文件与多个大文件

大文件上传源码&#xff0c;支持单个大文件与多个大文件 Ⅰ 思路Ⅱ 具体代码前端--单个大文件前端--多个大文件前端接口后端 Ⅰ 思路 具体思路请参考我之前的文章&#xff0c;这里分享的是上传流程与源码 https://blog.csdn.net/sugerfle/article/details/130829022 Ⅱ 具体代码…

C语言--插入排序

插入排序&#xff1a;简单而高效的排序算法 在计算机科学中&#xff0c;排序是一种常见的操作&#xff0c;用于将一组数据按照特定的顺序排列。插入排序&#xff08;Insertion Sort&#xff09;是一种简单直观的排序算法&#xff0c;它的工作原理类似于我们整理扑克牌的过程。…