并发编程-线程运行原理
首先我们要先知道jvm中有哪些区域,常见的就是栈,堆,方法区等,堆是创建对象时,对象的存储地址,方法区时代码生成字节码文件时存放的区域,栈呢,其实栈就是给线程的,每当线程运行时,虚拟机就会分配栈内存给线程,一个线程一个独立的栈内存,每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存 每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法
下面给演示一下示例代码
package n3;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.TestFrames")
public class TestFrames {
public static void main(String[] args) {
method1(10);
}
private static void method1(int x){
int y =x+1;
Object m=method2();
System.out.println(m);
}
private static Object method2(){
Object n=new Object();
return n;
}
}

程序运行过程
1,执行类加载过程将这个类的字节码文件加载到jvm的方法区中
2,会在stack中创建一个main主线程 并且分配内存,交给cpu去执行
3,main线程调用main方法,并创建一个main栈帧(局部变量表,args,返回地址,所记录,操作数栈) 局部变量表中存放的就是方法中的局部变量和方法参数
每个栈中都会有个程序计数器,用来记录程序执行到哪一步了,用来提供给cpu执行哪一行代码
4,main方法执行的时候,jvm会在堆中去创建一个newString[]数组,去给main方法的args参数赋值。返回地址就是代表的退出地址
5,main方法调用method1方法,并在main线程栈创建一个method1栈帧,局部变量表中存放的是method1方法中的局部变量和方法参数,返回地址就是方法区中method1方法退出后的地址
6,执行method1方法,创建一个method2栈帧,局部变量表中存放的是method2方法中的局部变量和方法参数,返回地址就是方法区中method2方法退出后的地址
7,执行method2方法,在堆区中创建了一个object的对象,并且返回,所以method1中m的值实际上是这个object对象
最后执行完成后进行销毁内存 根据返回地址一步一步的进行返回,最后stack中method2栈帧销毁,method1栈帧销毁,main栈帧销毁 main线程销毁
但是注意的每个线程的栈内存是相互独立的,互不影响,只不过每个线程的执行要很多因素的影响如cpu是几核的,线程是否拿到cpu的时间片等
这个就是接下来要将的线程的上下文切换
啥是线程的上下文切换,就是因为以下一些原因导致 cpu 不再执行当前的线程,转而执行另一个线程的代码
1,该线程cpu时间片用完
2,发生了垃圾回收,当垃圾回收发生的时候,所有的工作线程(业务线程)都要给垃圾回收线程进行线程让步
3,有更高优先级的线程运行
4,线程自己调用了sleep,join,wait等方法
当 Context Switch 发生时,需要由操作系统保存当前线程的状态,并恢复另一个线程的状态
Java 中对应的概念 就是程序计数器,它的作用是记住下一条 jvm 指令的执行地址,是线程私有的 状态包括程序计数器、虚拟机栈中每个栈帧的信息,如局部变量、操作数栈、返回地址等 Context Switch 频繁发生会影响性能
————————————————
版权声明:本文为CSDN博主「Kilsme11」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/2401_89739732/article/details/157257328
云服务器爆款直降90%
新客首单¥68起 | 人人可享99元套餐,续费同价 | u2a指定配置低至2.5折1年,立即选购享更多福利!