当前位置: 首页 > news >正文

JVM(HotSpot):虚拟机栈(JVM Stacks)与本地方法栈(Native Method Stacks)

文章目录

  • 一、内存结构图
  • 二、数据结构-栈
  • 三、JVM栈
  • 四、本地方法栈
  • 五、问题辨析
    • 1、垃圾回收是否涉及栈内存?
    • 2、栈内存越大越好吗?
    • 3、方法内的局部变量是否线程安全?
    • 4、栈内存溢出问题

一、内存结构图

在这里插入图片描述

二、数据结构-栈

数据结构中,栈的特点是什么?
简而言之:先进后出。
类比手枪的子弹夹

三、JVM栈

定义
1、每个线程运行时,所需要的内存。
2、每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存空间。
3、每个线程只能有一个活动栈帧,对应着程序当前执行的方法。

IDEA 演示
在这里插入图片描述在这里插入图片描述

四、本地方法栈

那些不是由Java编写的接口方法,比如用C语言或者C++语言开发的本地方法,让Java可以通过调用本地方法,来间接与操作系统更底层的相关API交互。
此时,运行本地方法所用的内存,就是本地方法栈。
比如Thread类里面,Object类里面的native方法,都是本地方法。
在这里插入图片描述

五、问题辨析

1、垃圾回收是否涉及栈内存?

答:不会,因为栈是给方法运行时的内存空间,所以,当方法执行完毕时,会自动释放内存。故而不需要GC来清理空间。

2、栈内存越大越好吗?

答:不是的。
栈内存和线程并发数有着相关关系。
当JVM总内存一定时,栈内存越大,那么,对应的线程数就越少。
比如,500MB的JVM内存,那么,栈内存设置为1MB,并发线程数理论上是500个,如果栈内存设置为10MB,那么,并发线程数就是50个。

设置栈内存
-Xss1m
在这里插入图片描述

3、方法内的局部变量是否线程安全?

答:判断变量是否安全的原则是,这个变量是否被多线程共享。
所以,方法内的局部变量是线程安全的。它不会被多个线程共享。

但是,要注意
方法内的局部变量,作用域不能逃出方法外,否则,依然是线程不安全的。
例如,入参和返参都是线程不安全的。
像下面的method1是安全的,method2,method3的sb变量是不安全的。

	private static void method1() {StringBuilder sb = new StringBuilder();sb.append(1);sb.append(1);sb.append(1);System.out.println(sb.toString());}private static void method2(StringBuilder sb) {sb.append(1);sb.append(1);sb.append(1);System.out.println(sb.toString());}private static StringBuilder method3() {StringBuilder sb = new StringBuilder();sb.append(1);sb.append(1);sb.append(1);return sb;}

4、栈内存溢出问题

1、栈内的栈帧过多,导致的内存溢出。
这种情况一般发生在递归调用的时候。

错误复现

public class Demo2 {private static int count;public static void main(String[] args) {try {method();} catch (Throwable e) {e.printStackTrace();System.out.println("运行次数:"+count);}}private static void method() {count++;method();}
}

在这里插入图片描述
还有可能是在对象数据格式化的时候出现。
比如,对象转json字符串。
如果出现,bean互相套用,也会出现无限循环的情况,导致StackOverflowError
2、栈帧过大导致的溢出。
这种情况是,方法内的局部变量太大了,直接超过了栈的内存,导致的。
比如,一个方法内,String 变量的值特别大,就可以导致这个错误发生。

相关文章:

  • 爬虫过程 | 蜘蛛程序爬取数据流程(初学者适用)
  • W39-02-jmeter中如何实现:下一个请求是需要根据前一个请求返回值进行循环请求
  • C++入门基础知识90(实例)——实例15【求两数的最大公约数】
  • 使用 MATLAB 处理和可视化 PCD 文件:点云过滤与保存的完整流程
  • Bigemap Pro首发(一款真正全面替代Arcgis的国产基础软件)
  • 《概率论与数理统计》学渣笔记
  • MATLAB无线网络设计工具:从理论到实践
  • TDengine 在业务落地与架构改造中的应用实践!
  • 【Redis入门到精通六】在Spring Boot中集成Redis(含配置和操作演示)
  • 计算机网络第六章——应用层
  • 速盾:cdn是怎么加速视频的?
  • 【解密 Kotlin 扩展函数】顶级函数和顶级属性(十五)
  • 极狐GitLab 17.4 重点功能解读【一】
  • springboot基于学习行为的学生选课成绩分析系统设计与实现
  • 计算机视觉实战项目4(图像分类+目标检测+目标跟踪+姿态识别+车道线识别+车牌识别+无人机检测+A*路径规划+单目测距与测速+行人车辆计数等)
  • 自己简单写的 事件订阅机制
  • Android交互
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • LeetCode算法系列_0891_子序列宽度之和
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • Tornado学习笔记(1)
  • 创建一种深思熟虑的文化
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 使用权重正则化较少模型过拟合
  • 通过npm或yarn自动生成vue组件
  • 优化 Vue 项目编译文件大小
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​2020 年大前端技术趋势解读
  • # linux从入门到精通(三)
  • (16)Reactor的测试——响应式Spring的道法术器
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (NSDate) 时间 (time )比较
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (分布式缓存)Redis哨兵
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (附源码)springboot电竞专题网站 毕业设计 641314
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (简单) HDU 2612 Find a way,BFS。
  • (离散数学)逻辑连接词
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • .Net Core中Quartz的使用方法
  • .考试倒计时43天!来提分啦!
  • /usr/bin/env: node: No such file or directory
  • @RestController注解的使用
  • @Service注解让spring找到你的Service bean
  • [1]-基于图搜索的路径规划基础
  • [2016.7 test.5] T1
  • [20171113]修改表结构删除列相关问题4.txt
  • [Angularjs]asp.net mvc+angularjs+web api单页应用之CRUD操作
  • [C#]C#学习笔记-CIL和动态程序集
  • [c]统计数字
  • [c++刷题]贪心算法.N01
  • [C语言]编译和链接