Hotspot源码解析-第十二章-线程栈保护页

了解保护页,先从几个问题开始吧

1、为什么线程栈有栈帧了,还要有保护页?

答:在操作系统中内存可以看成是一个大数组,这就有一个问题,线程之间可能会互相踩了别人的内存空间,所以栈空间也存在这个问题。为了防止栈溢出时破坏栈之外的数据结构,语言运行时会保留最大栈上限limit所在的一片区域,这就是保护页(Guard Page),也可叫哨兵值(Sentry)。当函数返回时检查保护页的值,如果被修改,说明已到达最大栈上限,此时就要输出错误并终止程序。

2、Java栈溢出后,保护页的作用?

答:Java也有栈溢出,发生时会抛出StackOverflowError,输出调用栈和代码行数。这些过程都需要额外执行很多方法,但是发生栈溢出就意味着不能继续执行方法了(因为方法执行需要栈空间)。为了解决这个问题,HotSpot虚拟机在C++语言运行时提供的保护页(Linux的JavaThread没有)之外会使用create_stack_guard_pages()创建额外的保护页来支持栈溢出错误处理,如图12-1所示。

3、保护页有几种类型及各类型的作用?

答:线程栈的最大上限处会保留三块保护页(Guard Page)支持栈溢出,分别是Reserved Page、Yellow Page、Red Page。图12-1中的主要内容分析如下:

1)Reserved Page:Reserved Page旨在为一些关键段(Critical Section)方法保存外栈空间,让有@ jdk.internal.vm.annotation.ReservedStackAccess注解的方法能完成执行(如lock与unlock之间的代码),防止关键段方法中的对象出现不一致的状态。当执行关键段方法时分配的栈顶触及Reserved Page,则虚拟机会将Reserved Page标记为正常栈空间,供关键段方法完成执行,然后再抛出StackOVerflowError。Reserved Page的大小由-XX:+StackReservedPages指定。

2)Yellow Page:如果执行Java代码时分配的栈顶触及YellowPage,则虚拟机会抛出StackOverflowError,然后将Yellow Page标为正常栈空间,让抛异常的代码有栈可用。Yellow Page的数量由参数-XX:StackYellowPages=指定,最后Yellow Page占用的空间是page数量*page大小(page的大小一般是4KB,如果开启-XX:+UseLargePages且操作系统支持large page特性,page的大小可达到4MB)。

3)Red Page:如果执行Java代码时分配的栈顶触及Red Page,则虚拟机会创建错误日志hs_err_pid.log然后关闭虚拟机。同样,为了让创建日志的代码执行,虚拟机会将Red Page标为正常栈空间。RedPage的大小由-XX:StackRedPages指定。

4)Shadow Page:前面区域都是执行Java代码出现栈溢出的错误处理。虚拟机还可能执行native方法或者虚拟机本身需要执行的方法,这些方法的栈大小不像Java代码一样能确定(编译器能确定但是虚拟机不能),如果开启虚拟机参数-XX:+UseStackBanging,JVM会分配一块足够大的Shadow Page执行,如果RSP(栈顶指针)超出Shadow Page区则抛出StackOverflowError。

有了create_stack_guard_pages()创建的额外的保护页,即便产生StackOverflowError,虚拟机也能执行额外的代码,正确地抛出Java异常并输出调用栈以提醒用户。

图12-1
在这里插入图片描述

图12-2 Java层面的栈布局
在这里插入图片描述

void JavaThread::create_stack_guard_pages() {if (!os::uses_stack_guard_pages() ||_stack_guard_state != stack_guard_unused ||(DisablePrimordialThreadGuardPages && os::is_primordial_thread())) {if (TraceThreadEvents) {tty->print_cr("Stack guard page creation for thread "UINTX_FORMAT " disabled", os::current_thread_id());}return;}// 这里为什么是栈基址减去栈大小呢,因为在Linux系统中,栈空间是从大到小开辟空间的,栈顶(ESP) <= 栈基址(EBP),正常栈基址EBP应该是在上面,而栈顶(ESP)是在下面,所以图12-1和图12-2实际上把它们倒过来看就行,画成正向的,是为了从概念上和感观上看更清晰address low_addr = stack_base() - stack_size();// 根据设置的Yellow Page数和Red Page数,然后乘以 page size,就可以得出要分配的空间size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size();int allocate = os::allocate_stack_guard_pages();// 通过create_stack_guard_pages函数从low_addr地址开始分配长度为len的区域,底层是通过mmap系统调用完成的if (allocate && !os::create_stack_guard_pages((char *) low_addr, len)) {warning("Attempt to allocate stack guard pages failed.");return;  // 分配失败,退出函数}// 通过系统调用mprotect,设置这块区域不可访问,也就是激活保护区if (os::guard_memory((char *) low_addr, len)) {_stack_guard_state = stack_guard_enabled;  // 设置激活保护区状态} else {// 激活失败,就通过uncommit_memory释放空间warning("Attempt to protect stack guard pages failed.");if (os::uncommit_memory((char *) low_addr, len)) {warning("Attempt to deallocate stack guard pages failed.");}}
}

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

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

相关文章

空间域图像增强之直方图均衡的python代码实现——冈萨雷斯数字图像处理

原理 直方图&#xff1a; 图像的直方图是一个图像中像素强度值分布的图表。 对于灰度图像&#xff0c;直方图展示了每个灰度级出现的频率。 直方图均衡步骤&#xff1a; 计算累积分布函数&#xff08;CDF&#xff09;&#xff1a;首先&#xff0c;计算图像的直方图&#xff0…

解决:ERROR: Failed building wheel for xxx

解决&#xff1a;ERROR: Failed building wheel for xxx 文章目录 解决&#xff1a;ERROR: Failed building wheel for xxx背景报错问题报错翻译报错原因解决方法参考内容&#xff1a;今天的分享就到此结束了 背景 在使用之前的代码构建环境时&#xff0c;报错&#xff1a;ERRO…

普中STM32-PZ6806L开发板(有点悲伤的故事续-人灯还未了)

简介 继上篇 普中STM32-PZ6806L开发板(有点悲伤的故事) 说到 关于 普中STM32-PZ6806L开发板的LED流水灯也被烧坏掉了&#xff0c;再也无法玩流水灯, 内心充满了只会流水灯的不甘, 流水灯就是单片机的Hello World&#xff0c;怎么能没有呢&#xff1f; 事情发展 好巧不巧想起最近…

Linux操作系统基础(10):Linux的特殊权限

1. 特殊权限是什么 在Linux中&#xff0c;特殊权限是指针对文件或目录的特殊权限设置&#xff0c;包括SetUID、SetGID和Sticky Bit。 SetUID&#xff08;Set User ID&#xff09;&#xff1a; 当一个可执行文件被设置了SetUID权限后&#xff0c;当任何用户执行该文件时&#x…

强大好用的低代码开发工具,yyds!

现在市面上的很多开发工具更侧重代码编辑&#xff0c;针对数据库增删改查&#xff08;CRUD&#xff09;类的Web系统开发&#xff0c;在界面设计、前后端数据交互等环节主要还是靠写代码&#xff0c;效率比较低&#xff1b;而现在市面上很多所谓的低代码开发平台&#xff0c;大多…

服务器经常出现自动重启怎么办

服务器自动重启是一个复杂且常见的问题&#xff0c;可能由多种原因引起。从硬件故障到软件问题&#xff0c;从电源问题到散热问题&#xff0c;每一个环节都可能成为服务器的杀手。在处理此类问题时&#xff0c;需要我们有一套完整的策略和方案&#xff0c;以便快速准确地定位并…

envoy在arm机器上的编译整理

版本信息&#xff1a; 操作系统:GUN Linux操作系统AARCH64架构。istio-proxy版本&#xff1a;istio-proxy1.15.2 编译环境搭建&#xff1a; 设置代理&#xff0c;确保可以访问Google等外网&#xff0c;这里envoy的第一次编译需要从外网下载依赖库。// 备注&#xff1a;这里一定…

决策树--分类决策树

1、介绍 ① 定义 分类决策树通过树形结构来模拟决策过程&#xff0c;决策树由结点和有向边组成。结点有两种类型&#xff1a;内部结 点和叶结点。内部结点表示一个特征或属性&#xff0c;叶子节点表示一个类。 ② 生成过程 用决策树分类&#xff0c;从根结点开始&#xff…

【自学笔记】01Java基础-09Java关键字详解

介绍java&#xff08;基于java11&#xff09;中所有关键字&#xff0c;以及主要重要的关键字详解。 1 Java 11中的关键字&#xff1a; 1.1 类型声明与变量定义 boolean&#xff1a;声明布尔类型变量&#xff0c;只有两个可能值 true 或 false。byte&#xff1a;声明一个8位有…

复制Ubuntu遇到的问题及解决办法、Ubuntu上git命令更改和查看账户、实现Ubuntu与Windows之间的文件共享

1、复制Ubuntu遇到的问题及解决办法 &#xff08;1&#xff09;问题一&#xff1a;“该虚拟机似乎正在使用中。如果该虚拟机未在使用&#xff0c;请按”获取所有权(T)”按钮获取它的所有权。否则&#xff0c;请按”取消(C)”按钮以防损坏。” 出现该问题的原因“未正确关闭虚…

关于java栈和堆

关于java栈和堆 在上一篇文章中我们了解了数组的声明和创建&#xff0c;本篇文章中我们了解一下声明数组&#xff0c;创建数组&#xff0c;给数组赋值以后&#xff0c;栈和堆都是怎么样子分配的&#xff0c;了解一下底层的逻辑知识&#xff0c;让大家可以更好的理解数组&#…

后端中的Dao层、Service层、Impl层、utils层、Controller层

Java Dao层 dao层叫数据访问层&#xff0c;全称为data access object&#xff0c;属于一种比较底层&#xff0c;比较基础的操作&#xff0c;具体到对于某个表、某个实体的增删改查&#xff0c;对外提供稳定访问数据库的方法 Mapper:&#xff08;DAO&#xff09; 访问数据库&am…

新品牌在小红书上宣传推广怎么做?

对于新品牌来说&#xff0c;如何在小红书进行有效的宣传推广&#xff0c;成为了一大挑战。本文伯乐网络传媒将为你揭秘新品牌在小红书上的宣传策略&#xff0c;助你牢牢抓住用户流量&#xff0c;提升品牌知名度。 小红书作为一款以内容为核心的社交电商平台&#xff0c;具有极高…

论文阅读:基于MCMC的能量模型最大似然学习剖析

On the Anatomy of MCMC-Based Maximum Likelihood Learning of Energy-Based Models 相关代码&#xff1a;点击 本文只介绍关于MCMC训练的部分&#xff0c;由此可知&#xff0c;MCMC常常被用于训练EBM。最后一张图源于Implicit Generation and Modeling with Energy-Based Mod…

开发知识点-Java网络编程-Netty

Netty P1 Netty-导学分布式网络返回 异步结果dubbo rabbitmqtest 测试案例多线程 日志 第1章_01_nio三大组件-channel-buffer网络编程 框架jdk 1.4 之后才有 nio这个 APIChannel 数据传输通道 &#xff08;双向&#xff09;Buffer 内存缓冲区 &#xff08;暂存Channel 的 数据&…

【React系列】Redux(三) state如何管理

本文来自#React系列教程&#xff1a;https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzg5MDAzNzkwNA&actiongetalbum&album_id1566025152667107329) 一. reducer拆分 1.1. reducer代码拆分 我们来看一下目前我们的reducer&#xff1a; function reducer(state ini…

jdk动态代理与cglib代理区别1

动态代理有jdk动态代理及cglib代理&#xff0c;下面描述jdk动态代理 jdk动态代理 看了 上云 老师的视频&#xff0c;整理下 pom文件 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starte…

JS函数实现数字转中文大写

JS函数实现数字转中文大写 1. 数字转字符,分割,去除空字符2. 遍历分割字符,替换为中文3. 增加四位数单位4. 处理零5. 拼接四位数据和单位 项目中,JS将万亿以下正整数转为中文大写 1. 数字转字符,分割,去除空字符 function toChineseNumber(num){const strs num.toString().re…

2023海内外零知识证明学习资料汇总(一)(故事中的零知识证明篇)

工欲善其事,必先利其器 Web3开发中&#xff0c;各种工具、教程、社区、语言框架.。。。 种类繁多&#xff0c;是否有一个包罗万象的工具专注与Web3开发和相关资讯能毕其功于一役&#xff1f; 参见另一篇博文&#x1f449; 2024最全面且有知识深度的web3开发工具、web3学习项目…

12 位多通道,支持 MPU 存储保护功能,应用于工业控制,智能家居等产品中的国产芯片ACM32F403/F433

ACM32F403/F433 芯片的内核基于 ARMv8-M 架构&#xff0c;支持 Cortex-M33 和 Cortex-M4F 指令集。芯片内核 支持一整套DSP指令用于数字信号处理&#xff0c;支持单精度FPU处理浮点数据&#xff0c;同时还支持Memory Protection Unit &#xff08;MPU&#xff09;用于提升应用的…