浅谈JVM基本结构

2023-11-03

目录

1.JVM概念

2.JVM基本结构

3.JVM存储数据案例


1.JVM概念

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

JVM类似于在操作系统之上运行的虚拟机软件:它能识别.class 字节码文件(java程序通过javac命令后编译产生的二进制代码),并且能够解析它的指令,最终调用操作系统上的函数,最终成功运行java文件。

总结来说就是JVM 是java程序和操作系统之间的桥梁,它的中间接口就是字节码。得益于JVM,他可以使得java程序可以跨平台在各种操作系统上运行。

jre文件中包含JVM环境。

2.JVM基本结构

JVM的基本结构如下图所示,java程序经过javac命令变成class file后进入jvm中进行处理:

(1)类加载器:

用于加载class文件。其可以分为 AppClassLoader(应用类加载器)、ExtClassLoader(拓展类加载器)、(根加载器,java程序无法获取)、虚拟机自带的加载器。

双亲委派机制: 即类加载器收到请求后,会向上委托给父类加载器,一直向上委托,启动加载器检查是否能加载当前类:能加载,结束;否则抛出异常,通知子类加载。

简单来说就是到最大的根加载器中有无该类,只有当根、拓展加载器都无该类,才会执行当前应用程序加载器。

通过双亲委派机制阻止代码去干涉核心类,守护了被信任的类库边界;将代码归入保护域,确定了代码可以执行哪些操作。

(2)本地方法栈和本地方法接口(JNI):

拓展java的使用,融合不同的编程语言使用。

凡是带了native关键字修饰的方法(该类方法没有方法体),说明java的作用范围达不到了,会进入本地方法栈,登记该方法。然后调用本地方法接口。

(3)程序计数器:

每一个线程私有的,指向方法区中的方法字节码(即线程的编号1,2,3…),占用内存空间小,几乎可以忽略不计。

(4)方法区:

被所有线程贡献,所有定义的东西(静态变量(static)、常量(final)、类信息(Class)、运行时的常量池)都存在方法区中

(5)栈:

要存放8大基本类型(局部变量,即方法中的变量)+对象的引用+实例的方法。

栈是一种数据结构,先进后出、后进先出。main方法执行后会进入java栈,然后调用的其他方法陆续进入。由于先进后出,所以main方法最后结束。即先入栈先调用,程序正在执行的方法一定在栈的顶部。

栈主管程序的运行,线程结束,栈内存即释放。

StackOverflowError:栈溢出,即方法相互递归调用不终止,不断将方法存入栈中,导致栈空间不足;还有就是启动的线程过多导致内存不足,导致的栈空间不足溢出。

(6)堆:

一个JVM只有一个堆内存,其大小是可以调整的。主要存放类、实例成员变量、数组。

可以分为新生区(Eden、survivor from 、survivor to)、老年区、永久区。

新对象会首先分配在 Eden 中(如果新对象过大,会直接分配在老年代中)。

进行轻GC时,Eden区中所有存活的对象都会被复制到“To”,而在“From”区中,仍存活的对象会根据他们的年龄值(经过GC的次数)来决定去向。年龄达到阈值的对象会被移动到年老代中,没有达到阈值的对象会被复制到“To”区域。经过这次GC后,Eden区和From区已经被清空。这个时候,"From"和"To"会交换他们的角色,也就是新的“To”就是上次GC前的"From",新的"From"就是上次GC前的"To"。

当幸存者区中对象经历了足够次数的GC后(-XX:MaxTenuringThreshold中设定的进入老年区的次数),会被移动到老年代。

3.JVM存储数据案例

下面通过代码,简单看看数据如何存储在 JVM中。

有以下两个类:

public class Student {
    private long id;
    private String name;
    private int age;
    
    public Student(long id,String name,int age){
        this.id = id;
        this.name = name;
        this.age = age;
    }
}
public class DataSave {
    public static void main(String[] args) {
        int num = 1;
        DataSave dataSave = new DataSave();
        dataSave.addOne(num);
        Student student = new Student(1,"test",18);
    }

    public void addOne(int i){
        i = i+1;
    }
}

上述定义消息都存于方法区中。

下面执行main程序:main线程入栈,开始执行。

(1)int num =1 ——> 局部变量,基础类型,引用和值都存在栈中。

(2)DataSave dataSave = new DataSave(); ——>新建对象dataSave ,对象dataSave 引用存在栈中,对象实例存在堆中。

(3)dataSave.addOne(num); ——> 方法 addOne()作为类的定义信息存于方法区中;调用addOne()方法,addOne()的栈帧(描述的是方法的一次执行瞬间,里面放的就是一些方法中的局部变量和方法的形参)入栈,开始执行。i为局部变量,引用和值存在栈中。当方法addOne()执行完成后,i就会从栈中消失。

(4)Student student = new Student(1,"test",18); ——>生成对象:student 为对象引用,存在栈中;对象new Student()存在堆中。

其中id, name, age为局部变量存储在栈中,且它们的类型为基础类型,因此它们的数据也存储在栈中;Student对象新建时调用构造函数获得的id, name, age为成员变量(即1, test,18),它们存储在堆中存储的new Student()对象里面;构造函数执行完毕,id, name, age从栈中消失。

(5)执行结束,num变量,DataSave,Student引用将从栈中消失;main线程出栈。

 以上便是一次代码执行过程中数据在JVM中的存储过程。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

浅谈JVM基本结构 的相关文章

  • Java JFileChooser 与过滤器据称仅显示目录无法仅显示目录

    预先感谢 如果您需要更多信息 请告诉我 示例代码位于底部 我试图解决的问题 我试图通过使用 javax swing filechooser FileFilter 对象来使此 JFileChooser 对象仅显示目录 而不是文件 该对象在ac
  • 我的应用程序中的 google+ 集成

    我是 Android 开发新手 正在创建一个带有 Google 集成的 Android 应用程序 我看到了一个教程并开始遵循它 但自教程以来 Google 已经更新了 Google 集成 例如 在本教程中您曾经单击 获取配置文件 按钮htt
  • Eclipse + Spring Boot 中“抛出 new SilentExitException()”处的断点

    每次我在 Eclipse IDE Spring Tool Suite 中以调试模式运行 Spring Boot 项目时 线程都会停止在throw new SilentExitException 即使没有断点也行 有什么解决方案可以避免这种行
  • 如何选择主题与队列

    当我们设计应用程序时如何选择Topic Queue类型实现 我知道 a 如果有多个消费者使用该消息 则使用 Topicb 如果只有一个消费者则使用Queue 请提供更多需要考虑的点 比如并发 消息持久化 负载均衡等等 Thanks Rw 如
  • 为什么这个 Java 静态字段为空?

    public class StaticTest private static String a private static String b this is a public static void main String args a
  • 在Java中,为什么equals()和hashCode()必须一致?

    如果我重写类上的任一方法 它必须确保如果A equals B true then A hashCode B hashCode也一定是真的 有人可以给我看一个简单的例子 如果违反了这一点 就会导致问题吗 我认为这与您是否使用该类作为 Hash
  • java中简单程序中的“未为类型定义方法”错误

    所以我只是想学习 Java 在观看了一些教程并阅读了一些基本内容之后 我对为什么它无法运行感到困惑 package Test public class TestProg public static void main String args
  • spring Kafka模型不在可信包中

    我正在研究微服务spring Kafka 2 1 5 and spring boot 2 0 5 第一个服务将向卡夫卡产生一些消息 第二个服务将消耗它们 在消耗时我遇到了问题 Caused by java lang IllegalArgum
  • 无法在 PHP 中接收 JSON POST 请求

    我正在将 JSON 对象从 Java 传递到 PHP 我正在使用 jdk 1 8 和 WAMPserver 下面是Java代码 import java io IOException import org apache http client
  • Log4j 2.x 如何实现惰性参数求值?

    鉴于Java 参数评估机制 http docs oracle com javase specs jls se8 html jls 15 html jls 15 12 4 2 如何Log4j 2 x实施惰性评估 https logging a
  • 使用 Hashmap 理解两个或多个键

    我的哈希图有问题 在我的哈希映射方法中 我希望有两个或多个关键字作为键 而不是只有一个 例如 我希望用户输入一些包含两个或多个关键字的句子 假设 教授姓名 是关键字 例如 String temp3 instructor teacher me
  • 面临 process.start(); 的问题在 Android 棒棒糖中

    面临一个问题process start 在 Android 棒棒糖中 我在服务中遇到了 android lollipop 后台进程的问题 我的代码在 KitKat 之前工作正常 我有一个ProcessBuilder pBuilder并向其中
  • Selenium - WebDriver.findElement() 和 WebElement.findElement() 之间的区别

    我正在使用WebElement findElement By cssSelector click 在页面上查找某个元素 但它返回了 Unable to locate element 但是当我使用WebDriver findElement B
  • 方法中缺少 return 语句错误

    我正在尝试编写一个返回计算机 MAC 地址字符串的静态方法 该函数本身可以在此处找到 http www mkyong com java how to get mac address in java http www mkyong com j
  • 在 libgdx 中截取屏幕截图

    我有一个应用程序 我想在其中截取游戏屏幕的屏幕截图并将其保存为图像并上传到 Facebook 我正在使用 Libgdx 我的重点是 android 谁能帮助我如何以编程方式截取游戏屏幕并将其另存为图像 现在相当容易 Libgdx提供了一个例
  • SwingWorker 和 Executor 的区别

    我正在使用 SwingWorker 在我正在制作的应用程序上执行一些重负载任务 虽然今天我遇到了 Executor 类和这个例子 Executors newCachedThreadPool execute new Runnable publ
  • Scala 不可变 Map 速度慢

    当我创建地图时 我有一段代码 val map gtfLineArr 8 split map split collect case Array k v gt k v toMap 然后我使用这张地图来创建我的对象 case class MyOb
  • allure2 侦听器在控制台中输出步骤

    我正在使用 Allure2 和 TestNG 我想编写自己的侦听器 在控制台输出中打印 Steps 我在 allure 中看到了 StepLifecycleListener 接口 但我无法在 TestNg 中实现此侦听器 有什么指点吗 Ov
  • 如何处理JFreeChart中的SpiderWebPlot?

    发现 JFreeChart 我在使用时遇到了问题蜘蛛网情节 http www jfree org jfreechart api javadoc org jfree chart plot SpiderWebPlot html 这就是我今天所拥
  • DocumentBuilder 解析产生无效字节 2 of 4 字节 UTF-8 序列错误

    我正在尝试解析包含字符串的字节数组Impresi n in XML final DocumentBuilderFactory builderFactory DocumentBuilderFactory newInstance final D

随机推荐

  • 【暴力破解】dvwa

    dvwa暴力破解练习 1 low 首先进行抓包 将包发送到intruder 然后对用户及密码进行暴力破解 成功 Mid 在low的基础上添加了一定的时延 不适合大量字典 但是爆破方式与low相同 High 点击进表单页面抓包包1 放掉之后再
  • parseInt()详解

    可能绝大多数学过js的就知道parseInt 函数 这里对小伙伴来说是有一个难点或者说是误区的 好吧 说的就是我 那就是在官方给的解释中我们能看到其中一个参数 radix 文中多次说他为基数 千万不要把它理解为要转换的进制 看上面的这些可能
  • docker 重启gitlab_Gitlab+CICD自动化部署Python项目

    使用CICD原理 当我们push项目到gitlab 就会触发 gitlab ci yml 文件 文件里面的 only maste表示 当push的分支为master则执行脚本 执行时通过tags shell选择已有的runner去执行 这时
  • 微信小程序——关于时间

    获取当前时间 var time new Date var year dateNow getFullYear var month dateNow getMonth 1 var day dateNow getDate var date year
  • 【2023最新版】Linux (WSL:Ubuntu22.04)安装Go1.20.6+Win11:安装Go1.20.6+GoLand2023.1.4+配置环境

    目录 一 Windows安装Go 1 下载地址 2 安装 3 配置Go环境变量 位置 默认添加的环境变量 修改环境变量 新建以下文件夹 检查 二 Linux WSL 安装Go 1 下载 2 解压缩 3 查看安装在系统上的Go版本 4 设置G
  • 《操作系统》- 操作系统的基本概念

    目录 一 操作系统的概念 1 1 操作系统的分类 1 2 计算机系统的构成 1 3 操作系统都做了哪些事 二 操作系统的目标和功能 2 1 操作系统的目标 2 2 操作系统的功能 三 操作系统的特征 3 1 并发 3 2 共享 3 3 虚拟
  • Java垃圾回收机制深入理解

    文章目录 一 简介 二 Java内存结构 三 什么是垃圾 四 垃圾收集算法 1 标记 清除算法 Mark and Sweep 2 复制算法 Copying 3 标记 整理算法 Mark and Compact 4 分代收集算法 Genera
  • 微软live服务器地址,在Mail中设置windows Live hotmail方法

    Mail是苹果系统的内置软件 是一款非常棒的软件 用起来很自然 起码和outlook比起来给人的感觉是这样 接下来是小编为大家收集的在Mail中设置windows Live hotmail方法 希望能帮到大家 在Mail中设置windows
  • c++ 在一行中输入若干个数,以空格间隔

    在一行中输入若干个数 以空格间隔 直到输入回车以结束 这是我在做PTA的题的时候发现回车输入逻辑有先后区别 题目如下 给出若干个正整数 请找出出现次数最多的数 输入格式 在一行中输入若干个数 以空格间隔 读入数的总个数不超过5000 输出格
  • ModuleNotFoundError: No module named ‘distutils.util 的解决方法

    ModuleNotFoundError No module named distutils util 的解决方法 使用 curl https bootstrap pypa io get pip py o get pip py sudo py
  • python轮胎缺陷检测_基于数字图像处理的轮胎缺陷检测

    摘要 随着汽车工业和道路交通运输业的迅猛发展 由于子午线轮胎具有胎面不容易变形 比较良好的稳定性 使用安全和耐用等特点 并且子午线轮胎的功能明显优越于普通斜交胎 其应用越来越普遍 已成为世界轮胎发展中的主要产品 但是子午线轮胎在制造过程中工
  • Navicat for mysql连接mysql时遇到的问题及其解决方法

    今天电脑重新装mysql 遇到了一个问题 authentication plugin caching 大概这样 懒得写了 找了好多教程 乱七八糟的就是解决不了 最后找到一篇博客https blog csdn net u011182575 a
  • 7. python爬虫——基于xpath爬取58同城房源信息

    python爬虫 基于xpath爬取58同城房源信息 1 需求 2 分析 3 代码 4 实现效果 1 需求 获取58同城上所有房源的标题信息 https bj 58 com ershoufang 2 分析 使用抓包工具进行分析 发现所有的房
  • vue2-element,vue3-element-plus 的列表翻页的序号

    前言 这里整理下 vue2 vue3中用饿了么框架的列表 序号随页增加的功能 vue2 page 当前页 pageSize 一页显示多少条 type index index indexMethod 序号翻页连续排序 indexMethod
  • 【踩坑笔记】从零开始在Linux和Windows部署安装kIash

    klash是一个基于规则的路由 可以为多地服务器之间配置特定的连接规则 加快后端业务响应速度 从零开始在Linux和Windows部署安装klash 一 材料准备 二 安装步骤 windows端 linux端 三 问题and踩坑 一 材料准
  • 敏捷开发流程

    一 敏捷起源 2001年2月 Martin Fowler Jim Highsmith等17位著名的软件开发专家齐聚在美国犹他州雪鸟滑雪圣地 举行了一次敏捷方法发起者和实践者的聚会 在这次会议上面 他们正式提出了Agile 敏捷开发 这个概念
  • 如何在php中获取curl请求的请求头信息及相应头信息

    1 获取请求头信息 可以在curl exec函数执行前 添加代码curl setopt ch CURLINFO HEADER OUT true 在curl exec函数执行后 通过 curl getinfo ch CURLINFO HEAD
  • dom模板列表-2

    模板列表
  • TensorRT 初探(1)—— conv2d:IConvolutionLayer

    tensorrt之conv2d计算详解 环境搭建 简介 代码 设置prepadding和postpadding prepadding postpadding与paddingNd冲突时 设置padding mode 总结 附录 环境搭建 环境
  • 浅谈JVM基本结构

    目录 1 JVM概念 2 JVM基本结构 3 JVM存储数据案例 1 JVM概念 JVM是Java Virtual Machine Java虚拟机 的缩写 JVM是一种用于计算设备的规范 它是一个虚构出来的计算机 是通过在实际的计算机上仿真