【JVM 内存结构 | 程序计数器】

news2024/11/24 15:47:39

内存结构

  • 前言
  • 简介
  • 程序计数器
    • 定义
    • 作用
    • 特点
    • 示例
    • 应用场景

在这里插入图片描述

主页传送门:📀 传送

前言


Java 虚拟机的内存空间由 堆、栈、方法区、程序计数器和本地方法栈五部分组成。

简介


  JVM(Java Virtual Machine)内存结构包括以下几个部分:

  • 堆区(Heap):堆区是最大的一块内存区域,由所有线程共享。所有的对象实例以及数组都在这块内存中分配。
  • 方法区(Method Area):方法区用于存储已被 JVM 加载的类信息、常量、静态变量,以及即时编译器编译后的代码等数据。
  • 栈(Stack):每个线程在创建时都会创建一个 JVM 栈,每个方法在执行的时候都会创建一个栈帧,用于存储局部变量、操作数栈、动态链接、方法出口等信息。
  • 程序计数器(Program Counter Register):这是一块较小的内存空间,可以看作是当前线程所执行的字节码指令的行号指示器。
  • 本地方法栈(Native Method Stack):与 JVM 栈类似,但是本地方法栈主要用于执行本地方法。

图示如下:

在这里插入图片描述
  JDK 1.8 同 JDK 1.7 比,最大的差别就是:元数据区取代了永久代。元空间的本质和永久代类似,都是对 JVM 规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元数据空间并不在虚拟机中,而是使用本地内存。

程序计数器


定义


  程序计数器(PC 寄存器)是一块较小的内存空间,它是一个专用的寄存器,用于存储当前正在执行的指令在指令序列中的位置。

作用


  • 按照顺序依次执行指令序列中的指令,当执行到跳转指令时,需要根据跳转指令的目标地址更新程序计数器的值,以便下一条指令能够正确执行。
  • 实现异常处理和中断服务。当程序出现异常或被中断时,程序计数器的值会被保存下来,以便在异常或中断处理结束后能够正确地继续执行程序。

特点


  • 线程隔离性:每个线程拥有自己的程序计数器,一个线程无法直接访问和修改另一个线程的程序计数器。
  • 内存占用小:程序计数器占用的内存空间非常小,可以忽略不计。
  • 无OutofMemoryError:程序计数器是Java虚拟机规范中唯一一个没有规定任何OutOfMemoryError的区域。
  • 执行时有值:程序执行的时候,程序计数器有值,其记录的是程序正在执行的字节码的地址。
  • 执行本地方法时值为空:执行native本地方法时,程序计数器的值为空。原因是native方法是Java通过jni调用本地C/C++库来实现,非Java字节码实现,所以无法统计。

示例

public class ProgramCounterExample {
    public static void main(String[] args) {
        ProgramCounter pc = new ProgramCounter();

        pc.increment();
        System.out.println(pc.getValue());  // 输出 1

        pc.decrement();
        System.out.println(pc.getValue());  // 输出 0

        pc.setValue(pc.getValue() + 1);
        System.out.println(pc.getValue());  // 输出 1
    }
}

class ProgramCounter {
    private int value;

    public ProgramCounter() {
        value = 0;
    }

    public void increment() {
        value++;
    }

    public void decrement() {
        value--;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}

应用场景


  • 指令执行控制:程序计数器可以用于实现指令流水线,即每条指令执行时,程序计数器会自动增加,指向下一条要执行的指令。
  • 实现跳转:当程序执行到跳转指令时,程序计数器需要根据跳转指令的目标地址更新自身的值,以便下一条指令能够正确执行。
  • 实现异常处理和中断服务:当程序出现异常或被中断时,程序计数器的值会被保存下来,以便在异常或中断处理结束后能够正确地继续执行程序。
  • 实现多线程:在多线程环境中,每个线程拥有自己的程序计数器,用于记录该线程正在执行的指令序列。

在这里插入图片描述

  如果喜欢的话,欢迎 🤞关注 👍点赞 💬评论 🤝收藏  🙌一起讨论
  你的支持就是我✍️创作的动力!					  💞💞💞

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

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

相关文章

关于CC2652的看门狗和系统时钟的我呢

看门狗 可以在CCS的syscfg的ui中配置&#xff0c;如下图 如果想看相关例程&#xff0c;可以电极最顶部watchdog旁边的问号 相关问题&#xff1a; 例程中没有添加hw_wdt的头文件&#xff0c;需要#include <ti/devices/cc13x2_cc26x2/inc/hw_wdt.h>&#xff0c;否则在获…

全面介绍ERP采购审批管理

在现代企业中&#xff0c;采购管理对于保障企业正常运营和维护供应链的稳定性至关重要。然而&#xff0c;传统的手动采购审批流程常常存在效率低下、易出错和缺乏可追溯性等问题。为了解决这些问题&#xff0c;越来越多的企业选择采用ERP采购审批管理方法&#xff0c;以实现更高…

CentOS7 TAR安装 EMQX(MQTT)

1、软件下载 官网 --> 右上角[免费试用] --> EMQX 下载 --> EMQX 开源版 --> 选择版本 系统 --> [免费下载] 选择 tar.gz amd64 --> [立即下载] 选择对应下载方式 上传到 /usr/local/ 目录下。 2、安装 #进入操作目录 cd /usr/local#创建安装目录 mk…

javascript常用的东西

JavaScript 是一门强大的编程语言&#xff0c;用于为网页添加交互性和动态性。也可以锻炼人们的逻辑思维&#xff0c;是一个非常好的东西。 一、变量和数据类型&#xff1a; 变量&#xff1a; 变量是用于存储数据值的容器。在 JavaScript 中&#xff0c;你可以使用 var、let…

ELK之LogStash介绍及安装配置

一、logstash简介 集中、转换和存储数据 Logstash 是免费且开放的服务器端数据处理管道&#xff0c;能够从多个来源采集数据&#xff0c;转换数据&#xff0c;然后将数据发送到您最喜欢的“存储库”中。 Logstash 能够动态地采集、转换和传输数据&#xff0c;不受格式或复杂度的…

2023.8 - java - Java 方法

什么是方法呢&#xff1f; Java方法是语句的集合&#xff0c;它们在一起执行一个功能。 方法是解决一类问题的步骤的有序组合方法包含于类或对象中方法在程序中被创建&#xff0c;在其他地方被引用 方法的命名规则 1.方法的名字的第一个单词应以小写字母作为开头&#xff0…

铁威马教程丨铁威马NAS如何使用安全顾问工具

在使用NAS的过程中&#xff0c;我们时常可能忽略了一些小细节&#xff0c;久而久之可能造成一定的风险&#xff0c;影响着我们NAS的健康。而使用铁威马NAS的安全顾问工具&#xff0c;可以快速地帮我们扫描系统设置是否安全&#xff0c;让我们更放心更安心地使用NAS。 安全顾问…

【Antd】Cascader 级联组件添加顶部栏(解决低版 antd 无 dropdownRender 属性方案)

文章目录 背景实现 背景 表单级联菜单需要添加表头&#xff0c;用于表示各级含义。 如果你的antd版本大于等于4.4.0&#xff0c;则直接可以使用dropdownRender 属性自定义&#xff0c;本篇文章可以直接跳过。 参数说明类型默认值版本dropdownRender自定义下拉框内容(menus: R…

LabVIEW利用线性压缩弹簧开发重量测量系统

LabVIEW利用线性压缩弹簧开发重量测量系统 柔性传感器的曲率半径相对于指定重量的变化特性可用作力测量方法。在许多应用中&#xff0c;例如&#xff1a;汽车和工业控制&#xff0c;计算机外围设备&#xff0c;操纵杆和测量设备&#xff0c;带有压缩弹簧和柔性传感器的重量测量…

【第三阶段】kotlin语言的takeUnless内置函数

1.takeUnless和takeif功能是相反的 username.takeif{true/false} true:返回username本身 false:返回null username.takeUnless{true/false} false:返回username本身 true:返回nullpackage Stage3 class Manager{private var info:String?nullfun getInfo()infofun setI…

ROS系统API接口

文章目录 一、 节点1. 节点初始化 ros API官网链接 一、 节点 1. 节点初始化 API名称&#xff1a;ros::init() ROS程序调用的第一个函数&#xff0c;用于对ROS程序的初始化。API常用形式&#xff1a; ros::init()函数最常见的使用方式为 ros::init(argc, argv, "my_n…

C++位域

Bit field 是什么&#xff1f; “ 位域 “ 或 “ 位段 “(Bit field)为一种数据结构&#xff0c;可以把数据以位的形式紧凑的储存&#xff0c;并允许程序员对此结构的位进行操作。这种数据结构的一个好处是它可以使数据单元节省储存空间&#xff0c;当程序需要成千上万个数据单…

Mybatis分页查询及特殊字符的处理

一. Mybatis分页查询 分页是我们在开发中绕不过去的一个坎&#xff01;当你的数据量大了的时候&#xff0c;一次性将所有数据查出来不现实&#xff0c;所以我们一般都是分页查询的&#xff0c;减轻服务端的压力&#xff0c;提升了速度和效率&#xff01;也减轻了前端渲染的压力…

如何使用海艺人工智能生成创意汉字

1、用某种字体生成文字。 jf storehttps://store.justfont.com/fonts 2、打开seaart。ai网站。https://www.seaart.ai/home 3、效果如下。 4、右键保存图片。

vue实现自定义树形组件

欢迎点击关注-前端面试进阶指南&#xff1a;前端登顶之巅-最全面的前端知识点梳理总结 *分享一个使用比较久的&#x1fa9c; 效果展示&#xff1a; 近期的一个功能需求&#xff0c;实现一个树形结构&#xff1a;可点击&#xff0c;可拖拽&#xff0c;右侧数据可以拖拽到对应的…

金融学复习博迪(第10-12章)

第4部分 风险管理与资产组合理论 第10章 风险管理的原理 10.1什么是风险 风险与风险规避 在证券市场上&#xff0c;风险是指由于投资环境的不确定性和变动性&#xff0c;而导致的投资者收益的不确定性和变动性。不确定性是风险的必要条件而非充分条件。任何一种存在风险的情…

【分享】小型园区组网场景

小型园区组网图 在小型园区中&#xff0c;S2700&S3700通常部署在网络的接入层&#xff0c;S5700&S6700通常部署在网络的核心&#xff0c;出口路由器一般选用AR系列路由器。 接入交换机与核心交换机通过Eth-Trunk组网保证可靠性。 每个部门业务划分到一个VLAN中&#…

【数据仓库】Linux、CentOS源码安装Superset

Linux、CentOS源码安装Superset步骤&#xff0c;遇到的各种问题。 报错问题&#xff1a; Linux下pip版本问题 You are using pip version 8.1.2, however version 22.2.2 is available. 解决办法&#xff1a; 安装python3的pip yum install python3-pip再升级 pip3 install…

127.0.0.1、0.0.0.0和网卡ip地址的区别及原理剖析

127.0.0.1、0.0.0.0和网卡ip地址的区别及原理剖析 问题描述 在最近一次采用前后端分离的方式部署本地应用的过程中发现&#xff0c;前端的node服务启动在5173端口上&#xff0c;而后端的springboot服务配置文件中定义的服务端口server.port也是5173端口&#xff0c;且两者都能…