上一篇文章我们搭建了JVM内存结构的整体框架,知道程序计数器、虚拟机栈、本地方法栈属于“线程私有区域”——每个线程启动时会单独分配内存,线程结束后内存直接释放,无需GC参与。这三个区域看似“小众”,却是理解线程执行逻辑、排查栈溢出异常的关键,也是面试中高频被问的考点。今天我们就深入拆解这三个区域,从“作用原理”到“异常场景”,再到“实战配置”,彻底搞懂线程私有区域的底层逻辑。

一、程序计数器:线程的“执行路标”,为何是唯一不会OOM的区域?

在多线程环境中,CPU会在不同线程间频繁切换——当线程A执行到一半被暂停,切换到线程B执行,等线程A再次获得CPU时,如何知道自己该从哪行代码继续执行?答案就藏在“程序计数器”里。
在这里插入图片描述

1. 程序计数器的核心作用:记录执行位置

程序计数器(Program Counter Register)的本质是一块“小型内存区域”,它的唯一作用是存储当前线程正在执行的字节码指令的地址(或行号) 。具体来说,有两种执行场景:

  • 当线程执行Java方法时,计数器存储的是“当前字节码指令的偏移地址”——比如OrderService.createOrder()方法对应的字节码文件中,第10行指令的地址;
  • 当线程执行Native方法时(如System.currentTimeMillis()),计数器的值会被设为“Undefined”——因为Native方法由C/C++实现,不属于Java字节码范畴,JVM无法跟踪其执行位置。

举个实际例子:假设线程A正在执行calculateSum(100)方法,执行到字节码的第20行(计算累加的关键步骤)时,CPU被切换到线程B。此时线程A的程序计数器会“记住”第20行的地址;当线程A再次获得CPU时,JVM会读取程序计数器中的地址,直接跳转到第20行继续执行,不会出现“重复执行”或“执行中断”的问题。

2. 为什么必须是“线程私有”?

这是新手最容易困惑的问题,答案其实和“线程切换”的特性直接相关:每个线程的执行路径、代码逻辑都是独立的——线程A在执行订单创建方法,线程B在执行支付回调方法,它们的字节码指令地址完全不同。如果程序计数器是“线程共享”的,那么线程切换时,计数器的值会被覆盖,导致线程恢复执行时找不到正确位置。

因此,JVM会为每个线程单独分配一块程序计数器内存,线程间的计数器值互不干扰——线程启动时创建,线程结束时销毁,全程与线程生命周期绑定,这就是“线程隔离”的底层保障之一。

3. 特殊点:唯一不会OOM的JVM内存区域

《Java虚拟机规范》明确规定:程序计数器的内存大小是“固定的”,不会随着线程执行过程动态扩展。它的内存大小取决于当前线程执行的方法——比如执行简单的getter方法,需要记录的指令地址较少,计数器占用内存就小;执行复杂的循环方法,指令地址虽多,但计数器仍能通过固定大小的内存存储(本质是地址值,占用空间有限)。

正因为内存大小固定,程序计数器永远不会出现“内存不足”的情况,也就成为了JVM中唯一不会抛出OutOfMemoryError的内存区域。这一点在面试中经常被问到,一定要记牢。

二、虚拟机栈:方法调用的“临时舞台”,栈溢出的根源在这里

如果说程序计数器是“执行路标”,那虚拟机栈就是线程执行方法的“临时舞台”——每个方法的调用、执行、返回,都对应虚拟机栈中“栈帧”的入栈、执行、出栈过程。理解虚拟机栈,就能搞懂“递归为什么会栈溢出”“局部变量存在哪里”这些实际问题。
在这里插入图片描述

1. 虚拟机栈的核心结构:栈帧的“四大部分”

虚拟机栈(Java Virtual Machine Stack)的本质是“栈式结构的内存区域”,其中存储的基本单位是“栈帧”(Stack Frame)。每个Java方法被调用时,JVM会创建一个对应的栈帧,并入栈;当方法执行完成(正常返回或抛出异常),栈帧会出栈并释放内存。

一个栈帧包含四大部分,我们用“调用UserService.getUserById(100)方法”为例,拆解每部分的作用:

(1)局部变量表:存储方法的局部变量

局部变量表是栈帧中最核心的部分之一,它存储方法的参数、局部变量,以及方法执行过程中创建的临时变量。比如getUserById(int id)方法中,参数id(值为100)、方法内定义的User user = null变量,都会存在局部变量表中。

局部变量表的大小在“编译期”就已确定——JVM会根据方法的参数和局部变量数量,计算出所需的“变量槽”(Slot)数量,并存入字节码文件中。比如一个int类型的变量占1个Slot,longdouble类型占2个Slot,对象引用(如User user)也占1个Slot(存储的是对象在堆中的地址)。<

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

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

相关文章

红帽认证升级华为openEuler证书活动!

如果您有红帽证书&#xff0c;可以升级以下相应的证书&#xff1a;&#x1f447; 有RHCSA证书&#xff0c;可以99元升级openEuler HCIA 有RHCE证书&#xff0c;可以99元升级openEuler HCIP 有RHCA证书&#xff0c;可以2100元升级openEuler HCIE 现金激励&#xff1a;&#x1f4…

迭代器模式与几个经典的C++实现

迭代器模式详解1. 定义与意图迭代器模式&#xff08;Iterator Pattern&#xff09; 是一种行为设计模式&#xff0c;它提供一种方法顺序访问一个聚合对象中的各个元素&#xff0c;而又不暴露该对象的内部表示。主要意图&#xff1a;为不同的聚合结构提供统一的遍历接口。将遍历…

epoll 陷阱:隧道中的高级负担

上周提到了 tun/tap 转发框架的数据通道结构和优化 tun/tap 转发性能优化&#xff0c;涉及 RingBuffer&#xff0c;packetization 等核心话题。我也给出了一定的数据结构以及处理逻辑&#xff0c;但竟然没有高尚的 epoll&#xff0c;本文说说它&#xff0c;因为它不适合。 epo…

微前端架构常见框架

1. iframe 这里指的是每个微应用独立开发部署,通过 iframe 的方式将这些应用嵌入到父应用系统中,几乎所有微前端的框架最开始都考虑过 iframe,但最后都放弃,或者使用部分功能,原因主要有: url 不同步。浏览器刷新 iframe url 状态丢失、后退前进按钮无法使用。 UI 不同…

SQL Server更改日志模式:操作指南与最佳实践!

全文目录&#xff1a;开篇语**前言****摘要****概述&#xff1a;SQL Server 的日志模式****日志模式的作用****三种日志模式**1. **简单恢复模式&#xff08;Simple&#xff09;**2. **完整恢复模式&#xff08;Full&#xff09;**3. **大容量日志恢复模式&#xff08;Bulk-Log…

git的工作使用中实际经验

老输入烦人的密码 每次我git pull的时候都要叫我输入三次烦人的密码&#xff0c;问了deepseek也没有尝试成功 出现 enter passphrase for key ‘~/.ssh/id_rsa’ 的原因: 在生成key的时候,没有注意,不小心设置了密码, 导致每次提交的时候都会提示要输入密码, 也就是上面的提示…

科技赋能,宁夏农业绘就塞上新“丰”景

在贺兰山的巍峨身影下&#xff0c;在黄河水的温柔滋养中&#xff0c;宁夏这片古老而神奇的土地&#xff0c;正借助农业科技的磅礴力量&#xff0c;实现从传统农耕到智慧农业的华丽转身&#xff0c;奏响一曲科技与自然和谐共生的壮丽乐章。一、数字农业&#xff1a;开启智慧种植…

imx6ull-驱动开发篇36——Linux 自带的 LED 灯驱动实验

在之前的文章里&#xff0c;我们掌握了无设备树和有设备树这两种 platform 驱动的开发方式。但实际上有现成的&#xff0c;Linux 内核的 LED 灯驱动采用 platform 框架&#xff0c;我们只需要按照要求在设备树文件中添加相应的 LED 节点即可。本讲内容&#xff0c;我们就来学习…

深度学习中主流激活函数的数学原理与PyTorch实现综述

1. 定义与作用什么是激活函数&#xff1f;激活函数有什么用&#xff1f;答&#xff1a;激活函数&#xff08;Activation Function&#xff09;是一种添加到人工神经网络中的函数&#xff0c;旨在帮助网络学习数据中的复杂模式。类似于人类大脑中基于神经元的模型&#xff0c;激…

Linux高效备份:rsync + inotify实时同步

一、rsync 简介 rsync&#xff08;Remote Sync&#xff09;是 Linux 系统下的数据镜像备份工具&#xff0c;支持本地复制、远程同步&#xff08;通过 SSH 或 rsync 协议&#xff09;&#xff0c;是一个快速、安全、高效的增量备份工具。二、rsync 特性 支持镜像保存整个目录树和…

一种通过模板输出Docx的方法

起因在2个群里都有网友讨论这个问题&#xff0c;俺就写了一个最简单的例子。其实&#xff0c;我们经常遇到一些Docx的输出的需求&#xff0c;“用模板文件进行处理”是最简单的一个方法&#xff0c;如果想预览也简单 DevExpress 、Teleric 都可以&#xff0c;而且也支持 Web 、…

探索 List 的奥秘:自己动手写一个 STL List✨

&#x1f4d6;引言大家好&#xff01;今天我们要一起来揭开 C 中 list 容器的神秘面纱——不是直接用 STL&#xff0c;而是亲手实现一个简化版的 list&#xff01;&#x1f389;你是不是曾经好奇过&#xff1a;list 是怎么做到高效插入和删除的&#xff1f;&#x1f50d;迭代器…

mysql占用高内存排查与解决

mysql占用高内存排查-- 查看当前全局内存使用情况&#xff08;需要启用 performance_schema&#xff09; SELECT * FROM sys.memory_global_total; -- 查看总内存使用 SELECT * FROM sys.memory_global_by_current_bytes LIMIT 10; -- 按模块分类查看内存使用排行memory/perfor…

构建真正自动化知识工作的AI代理

引言&#xff1a;新一代生产力范式的黎明 自动化知识工作的人工智能代理&#xff08;AI Agent&#xff09;&#xff0c;或称“智能体”&#xff0c;正迅速从理论构想演变为重塑各行各业生产力的核心引擎。这些AI代理被定义为能够感知环境、进行自主决策、动态规划、调用工具并持…

青少年机器人技术(四级)等级考试试卷-实操题(2021年12月)

更多内容和历年真题请查看网站&#xff1a;【试卷中心 -----> 电子学会 ----> 机器人技术 ----> 四级】 网站链接 青少年软件编程历年真题模拟题实时更新 青少年机器人技术&#xff08;四级&#xff09;等级考试试卷-实操题&#xff08;2021年12月&#xff09; …

最新短网址源码,防封。支持直连、跳转。 会员无广

最新短网址源码&#xff0c;防封。支持直连、跳转。 会员无广告1.可将长网址自动缩短为短网址&#xff0c;方便记忆和使用。2.短网址默认为临时有效&#xff0c;可付费升级为永久有效&#xff0c;接入支付后可自动完成&#xff0c;无需人工操作。3.系统支持设置图片/文字/跳转页…

缓存-变更事件捕捉、更新策略、本地缓存和热key问题

缓存-基础知识 熟悉计算机基础的同学们都知道&#xff0c;服务的存储大多是多层级的&#xff0c;呈现金字塔类型。通常来说本机存储比通过网络通信的外部存储更快&#xff08;现在也不一定了&#xff0c;因为网络传输速度很快&#xff0c;至少可以比一些过时的本地存储设备速度…

报表工具DevExpress .NET Reports v25.1新版本亮点:AI驱动的扩展

DevExpress Reporting是.NET Framework下功能完善的报表平台&#xff0c;它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集&#xff0c;包括数据透视表、图表&#xff0c;因此您可以构建无与伦比、信息清晰的报表。 DevExpress Reporting控件日前正式发布了v25.1…

kubernetes中pod的管理及优化

目录 2 资源管理方式 2.1 命令式对象管理 2.2 资源类型 2.2.1 常用的资源类型 2.2.2 kubectl常见命令操作 2.3 基本命令示例 2.4 运行和调试命令示例 2.5 高级命令示例 3 pod简介 3.1 创建自主式pod&#xff08;生产环境不推荐&#xff09; 3.1.1 优缺点 3.1.2 创建…

解释一下,Linux,shell,Vmware,Ubuntu,以及Linux命令和shell命令的区别

Linux 操作系统概述Linux 是一种开源的类 Unix 操作系统内核&#xff0c;由 Linus Torvalds 于 1991 年首次发布。作为现代计算的基础设施之一&#xff0c;它具有以下核心特征&#xff1a;多用户多任务特性允许多个用户同时操作系统资源&#xff0c;而模块化设计使其能够适应从…