虚拟机栈
-
由于跨平台设计,java指令都是根据栈来设计的,不同平台的CPU架构不同,所以不能基于寄存器,基于栈设计有点在于跨平台,指令集小,编译器容易实现,缺点在于性能下降,实现同样的功能需要更多的指令
-
栈是运行时单位,堆是存储单位
- 栈解决程序的运行问题,程序如何执行或者说如何处理数据
- 堆解决数据存储问题,数据怎么放,放哪里
-
java虚拟机栈 Java Virtual Machine Stack 早期叫JAVA栈 每个线程在创建的时候会创建一个虚拟机栈,其内部保存了一个个栈帧Stack Frame 对应着一次java方法的调用,虚拟机栈是每一个线程私有的
-
生命周期与线程一致
-
主要java程序的运行,他保存方法的局部变量,部分结果,参与方法的调用和返回
-
栈是一种快速优先的分配存储方式,访问速度仅次于PC寄存器,JVM对java栈的操作只有两种出栈和压栈
- 每个方法直接伴随入栈
- 执行结束后出栈
- 对于栈来说不存在垃圾回收问题 但会出现栈溢出 StackOverFlow 或者OutOfMemory
-
JVM规范允许java栈的大小是动态的或者固定不变的
-
如果采用固定大小java虚拟机栈,每个线程的java虚拟机栈容量可以线程创建的时候单独选定,如果线程请求分配的栈容量大于java虚拟机栈指定的最大容量,JVM会抛出StackOverFlowError异常
-
如果java虚拟机栈是动态扩展的,当尝试扩展的时候无法申请到足够的内存,或者创建新栈的时候没有内存,JVM会抛出OutOfMemoryError异常
-
设置栈内存大小 -Xss
- Sets the thread stack size (in bytes). Append the letter
k
orK
to indicate KB,m
orM
to indicate MB, andg
orG
to indicate GB. The default value depends on the platform: - Linux/x64 (64-bit): 1024 KB
- macOS (64-bit): 1024 KB
- Oracle Solaris/x64 (64-bit): 1024 KB
- Windows: The default value depends on virtual memory
-Xss1m -Xss1024k -Xss1048576
- Sets the thread stack size (in bytes). Append the letter
-
栈的存储单位 每个线程都有自己的栈,栈中的数据都以栈帧的格式存在,每个线程上正常执行的每个方法都有各自对应的栈帧,栈帧是一个内存区块,是一个数据集,维系着方法执行过程中的各种数据信息
-
栈存储类和对象信息,类的基本结构 field 和method
-
JVM对栈操作只有两种 push pop FIFO
-
在一个活动线程中,一个时间点上,只会有一个活动栈帧.即当前正在执行的方法的栈帧是有效的,这个栈被称为当前栈Current Frame,与当前栈对应的方法就是当前方法Current Method,与当前方法对应的类就是当前类 Current Class
-
执行引擎运行的所有字节码指令只针对当前栈帧进行操作
-
如果在方法中调用了其他方法,对应新的栈帧就会被创建,压入栈顶,称为新的当前栈
-
栈运行原理
- 不同线程中所包含的栈帧是不允许相互存在引用的,即不可能在一个栈帧中引用到另外一个线程的栈帧
- 如果当前方法调用了其他方法,方法返回之际,当前栈帧会传回次方法的执行结果给上一帧,接着虚拟机丢弃当前栈帧,上一帧重新成为新的当前栈帧
- java方法有两种返回函数的方式,一种是正常函数返回,使用return指令;另外一种是抛出异常,无论哪种方式都会导致JVM将栈帧弹出
-
栈帧的内部结构
- 局部变量表 Local Varibles
- 操作数栈 Operand Stack
- 动态链接 Dynamic Lingking
- 方法返回地址 Return Address
- 一些附加信息
-
栈帧的大小主要取决于局部变量表和操作数栈