4. 虚拟机栈

发布于:2025-07-13 ⋅ 阅读:(12) ⋅ 点赞:(0)

1. JVM介绍和运行流程-CSDN博客

2. 什么是程序计数器-CSDN博客

3. java 堆和 JVM 内存结构-CSDN博客

4. 虚拟机栈-CSDN博客

5. JVM 的方法区-CSDN博客

6. JVM直接内存-CSDN博客

7. JVM类加载器与双亲委派模型-CSDN博客

8. JVM类装载的执行过程-CSDN博客

9. JVM垃圾回收-CSDN博客

10. 垃圾回收的算法-CSDN博客

11. JVM中的分代回收-CSDN博客

12. JVM的垃圾回收器-CSDN博客

13. G1垃圾回收器-CSDN博客

14. 垃圾回收的引用区别-CSDN博客

15. JVM调优的参数设置-CSDN博客

 16. JVM调优工具-CSDN博客


1. 什么是虚拟机栈

虚拟机栈是 Java虚拟机(JVM) 运行时数据区的一部分,是线程私有的内存区域,每个线程在创建时都会创建一个虚拟机栈。

简单来说就是:每个线程运行时所需要的内存,称为虚拟机栈,先进后出。

主要特点:

  1. 线程私有:每个线程都有自己独立的虚拟机栈  
  2. 生命周期:与线程相同,随线程创建而创建,随线程结束而销毁  
  3. 存储内容:存储栈帧(Stack Frame),即方法调用的数据结构  
  4. 异常:可能抛出StackOverflowError(栈深度超过限制)和OutOfMemoryError(无法扩展栈时)

2. 栈帧

栈帧(frame)是虚拟机栈的基本组成单元,是用于支持 Java 方法调用和执行的数据结构。

每次方法调用时,JVM都会创建一个新的栈帧并压入虚拟机栈;

方法执行结束时,对应的栈帧会被弹出。

栈帧 和 栈 的关系:

整体与部分的关系:

  • 虚拟机栈是由多个栈帧组成的后进先出(LIFO)的数据结构
  • 每个栈帧对应一个方法调用(每个线程(栈)只能有一个活动栈帧,对应着当前正在执行的那个方法)

生命周期关系

  • 线程启动时创建虚拟机栈

  • 方法调用时创建栈帧并压入栈

  • 方法结束时弹出栈帧

  • 线程结束时销毁虚拟机栈

 3. 常见问题

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

垃圾回收主要指的就是堆内存,当栈帧弹出之后,内存就会释放。

3.2 栈内存分配越大越好吗?

未必,默认的栈内存通常为 1024k
栈帧过大会导致线程数变少,例如,机器总内存为 512m,目前能活动的线程数则为 512 个,如果把栈内存改为 2048k,那么能活动的栈帧就会减半。

3.3 栈内的局部变量是否线程安全?

  • 如果方法内局部变量没有逃离方法的作用范围,它是线程安全的
  • 如果是局部变量引用了对象,并逃离方法的作用范围,需要考虑线程安全 

3.4 栈内存溢出的情况 

  • 栈帧过多导致栈内存溢出,典型问题:递归调用
  • 栈帧过大导致栈内存溢出(不太常见)

3.5 堆和栈的区别 

  • 栈内存一般会用来存储局部变量和方法调用,但堆内存是用来存储Java对象和数组的的。堆会GC垃圾回收,而栈不会。
  • 栈内存是线程私有的,而堆内存是线程共有的。
  • 两者异常错误不同,但如果栈内存或者堆内存不足都会抛出异常。栈空间不足:java.lang.StackOverFlowError。堆空间不足:java.lang.OutOfMemoryError.
特性 堆(Heap) 栈(Stack)
存储内容 对象实例 基本类型变量、对象引用
线程共享 每个线程私有
内存分配 动态 固定大小(可通过参数调整)
垃圾回收 否(随线程结束自动释放)
空间大小 较大 较小
分配效率 相对较慢 相对较快


网站公告

今日签到

点亮在社区的每一天
去签到