栈与栈帧
JVM中由堆、栈、方法区组成。每个线程启动后,虚拟机就会为其分配一块栈内存。
- 每个栈由多个栈帧(Frame)组成,对应每次方法调用时所占的内存
- 每个线程只能有一个活动栈帧,对应当前正在执行的方法
- 一个栈帧包含局部变量、操作数栈、动态链接、返回值等信息
- 方法结束之后栈帧即被释放
类运行过程
- 将类中的各种方法的字节码加载到内存中的方法区
- JVM启动名为main的主线程并给其分配栈内存
- 将线程交给任务调度器运行
- JVM分配主方法(入口方法)的栈帧内存(栈帧创建时其内部成员的内存即被分配好)
- 栈帧分配完毕后即可运行方法内部的代码
- 调用其他方法时JVM分配其他方法的栈帧
- 方法调用完毕后栈帧即被销毁,后续再次调用会重新分配栈帧
局部变量表
由虚拟机在堆中生成该方法的变量对象并将其变量存储在局部变量表中
线程上下文切换(Thread Context Switch)
因为一下原因导致CPU不再执行当前的线程时就会发生线程上下文切换
- 线程的CPU时间片用完
- 垃圾回收
- 有更高优先级的线程需要运行
- 线程自己调用了
sleep
、yield
、wait
、join
、synchroized
、lock
等方法
当CS发生时,需要由操作系统保存当前线程的状态,并恢复另一个线程的状态,Java中对应的概念是程序计数器(与计算机组成原理中的PC寄存器略有不同,此处的计数器是系统级而不是硬件级),他的作用是记录下一条jvm指令的地址,是线程私有的
- 线程的状态包括计数器、虚拟机栈中每个栈帧的信息,如局部变量、操作数栈巴拉巴拉
- Context Switch频繁发生会影响性能