“`”
<h4>1.3.1 图解进程和线程的关系</h4>
下图是 Java 内存区域,通过下图我们从 JVM 的角度来说一下线程和进程之间的关系。
<img src=""http://res.mianshigee.com/upload/article/20200214/a797ebb8-c29b-4b48-8839-171196e29d25.png"" style=""width: 100%;""><br>
从上图可以看出:一个进程中可以有多个线程,多个线程共享进程的<strong>堆</strong>和<strong>方法区 (JDK1.8 之后的元空间)</strong>资源,但是每个线程有自己的<strong>程序计数器</strong>、<strong>虚拟机栈</strong> 和 <strong>本地方法栈</strong>。
下面来思考这样一个问题:为什么<strong>程序计数器</strong>、<strong>虚拟机栈</strong>和<strong>本地方法栈</strong>是线程私有的呢?为什么堆和方法区是线程共享的呢?</p>
<h4>1.3.2 程序计数器为什么是私有的?</h4>
程序计数器主要有下面两个作用:
<ol><li>字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。</li><li>在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。</li></ol>
需要注意的是,如果执行的是 native 方法,那么程序计数器记录的是 undefined 地址,只有执行的是 Java 代码时程序计数器记录的才是下一条指令的地址。
所以,程序计数器私有主要是为了<strong>线程切换后能恢复到正确的执行位置</strong>。
<h4>1.3.3 虚拟机栈和本地方法栈为什么是私有的?</h4>
<ul><li><strong>虚拟机栈:</strong>每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。</li><li><strong>本地方法栈:</strong>和虚拟机栈所发挥的作用非常相似,区别是: <strong>虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。</strong> 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。</li></ul>
所以,为了<strong>保证线程中的局部变量不被别的线程访问到</strong>,虚拟机栈和本地方法栈是线程私有的。
<h4>1.3.4 一句话简单了解堆和方法区</h4>
堆和方法区是所有线程共享的资源,其中堆是进程中最大的一块内存,主要用于存放新创建的对象 (所有对象都在这里分配内存),方法区主要用于存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
<pre><code> "“`
Was this helpful?
0 /
0