虚拟机角度下的线程
jvm与线程
一个 Java 应用程序通常只包含一个 JVM 进程(Java Virtual Machine,Java虚拟机),但在某些情况下可能会有多个 JVM 进程。 一个 Java 应用通常是一个进程,这个进程就是jvm,编译好的class文件丢到jvm中,执行时就成为了诸多线程(网络请求过来时,也会生成相应的线程去处理请求)。当运行一个 Java 程序时,操作系统会创建一个 JVM 进程,该进程会解释和执行 Java 代码,从而运行您的程序。 ——我们编写的Java程序运行在一个jvm上面,一个jvm囊括了所有的线程,所有的需求都是由线程完成的。
jvm中的线程
来看一下线程在jvm中是如何存在的:
下图为虚拟机中的运行时数据区:
在其中:方法区、堆是公共的,虚拟机栈、pc寄存器(程序计数器)、本地方法栈是线程私有的。
为什么是私有的?(八股)
-
虚拟机栈:每个线程在执行Java程序时都需要有自己独立的虚拟机栈,用于存储方法调用时的局部变量表、操作数栈、动态链接、方法出口等信息。因为每个线程执行的方法可能不同,所以虚拟机栈需要根据具体的线程和方法进行动态分配和释放。如果虚拟机栈是共享的,就会导致不同线程之间的方法调用信息相互干扰,严重影响程序的正确性和可靠性。
-
程序计数器:每个线程在执行Java程序时都需要有自己独立的程序计数器,用于记录当前线程正在执行的指令的地址。程序计数器是线程私有的,因为不同的线程可能在同时执行不同的方法,如果多个线程共享同一个程序计数器,就会导致多个线程互相干扰,无法正确执行。
-
本地方法栈:本地方法栈用于执行本地方法(由其他语言编写的方法),与虚拟机栈类似,它也包含局部变量表、操作数栈、动态链接、返回地址等信息。每个线程在执行本地方法时都需要有自己独立的本地方法栈,因为本地方法的调用与Java方法的调用有很大的不同之处,需要有独立的栈空间进行管理。如果本地方法栈是共享的,就会导致不同线程之间的本地方法调用信息相互干扰,严重影响程序的正确性和可靠性。
总之,虚拟机栈、程序计数器、本地方法栈都是线程私有的内存区域,每个线程都需要有自己独立的栈空间进行管理,以保证程序的正确性和可靠性。
堆和方法区
堆和方法区(元空间)是所有线程共享的资源,其中堆是进程中最大的一块内存,主要用于存放新创建的对象 (几乎所有对象都在这里分配内存),方法区主要用于存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。