从 JVM ⻆度说进程和线程之间的关系

1. 图解进程和线程的关系

下图是 Java 内存区域,通过下图我们从 JVM 的⻆度来说⼀下线程和进程之间的关系。如果你对 Java 内存区域(运⾏时数据区)这部分知识不太了解的话可以阅读⼀下这篇⽂章:《可能是把Java 内存区域讲的最清楚的⼀篇⽂章》

file
从上图可以看出:⼀个进程中可以有多个线程,多个线程共享进程的⽅法区(JDK1.8 之后的元空间)资源,但是每个线程有⾃⼰的程序计数器虚拟机栈本地⽅法栈

总结: 线程是进程划分成的更⼩的运⾏单位。线程和进程最⼤的不同在于基本上各进程是独⽴的,⽽各线程则不⼀定,因为同⼀进程中的线程极有可能会相互影响。线程执⾏开销⼩,但不利于资源的管理和保护;⽽进程正相反

下⾯是该知识点的扩展内容!
思考这样⼀个问题:为什么程序计数器、虚拟机栈和本地⽅法栈是线程私有的呢?为什么堆和⽅法区是线程共享的呢?

2. 程序计数器为什么是私有的?

程序计数器主要有下⾯两个作⽤:

  1. 字节码解释器通过改变程序计数器来依次读取指令,从⽽实现代码的流程控制,如:顺序执⾏、选择、循环、异常处理。
  2. 在多线程的情况下,程序计数器⽤于记录当前线程执⾏的位置,从⽽当线程被切换回来的时候能够知道该线程上次运⾏到哪⼉了。

需要注意的是,如果执⾏的是 native ⽅法,那么程序计数器记录的是 undefined 地址,只有执⾏的是 Java 代码时程序计数器记录的才是下⼀条指令的地址。

所以,程序计数器私有主要是为了线程切换后能恢复到正确的执⾏位置

3. 虚拟机栈和本地⽅法栈为什么是私有的?

  • 虚拟机栈:每个 Java ⽅法在执⾏的同时会创建⼀个栈帧⽤于存储局部变量表、操作数栈、常量池引⽤等信息。从⽅法调⽤直⾄执⾏完成的过程,就对应着⼀个栈帧在 Java 虚拟机栈中⼊栈和出栈的过程。
  • 本地⽅法栈:和虚拟机栈所发挥的作⽤⾮常相似,区别是:虚拟机栈为虚拟机执⾏ Java ⽅法(也就是字节码)服务,⽽本地⽅法栈则为虚拟机使⽤到的 Native ⽅法服务。在 HotSpot 虚拟机中和 Java 虚拟机栈合⼆为⼀。

所以,为了保证线程中的局部变量不被别的线程访问到,虚拟机栈和本地⽅法栈是线程私有的。

4. ⼀句话简单了解堆和⽅法区

堆和⽅法区是所有线程共享的资源,其中堆是进程中最⼤的⼀块内存,主要⽤于存放新创建的对象(所有对象都在这⾥分配内存),⽅法区主要⽤于存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

最后修改日期: 2021年11月26日

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。