线程 工作内存

计算机的工作方式是基于冯诺依曼结构的,从磁盘读取数据到内存,再从内存读取数据到cpu内部的三级,二级,一级最后到达寄存器。java中的多线程的主内存就是内存上面的 jvm 堆,程序在运行时的线程所要的数据都是来自内存,读取并最终传入cpu内部寄存器,每个cpu内部都有各自的一套完整寄存器,cpu只能直接操作这些寄存器,比如cpu的加法指令吧两个寄存器里面的数据加起来放入其中一个或者地三个寄存器,计算的结果如需要保存,cpu需要另一个指令吧数据传输到数据总线并保存到内存,最终写回磁盘。在这个过程中,内存数据可能被多个线程同时读取,并在cpu内部形成私有的拷贝,就是本地内存 (内存的cpu内部本地副本) 在线程中体现在 线程栈 区,正是这种分步多指令实现一个操作,在多线程被调度置换过程中数据被多个线程操作,造成数据竞争,所以数据经常用到锁等手段实现同步。

上面从硬件的实现角度看,从软件的角度看,线程可访问的数据就分共享数据,和私有数据,这个在不同的计算机编程语言中体现都不一样,比如java中的类属性就可以是共享的也可以是私有的,当这个类的实例是在方法内部创建的,那属性就是线程私有的,因为整个对象都是线程私有的,如果该对象被传到线程中的方法,该对象就是共享的。这个界限就看数据是在哪里产生和多线程可访问性;线程防范内部产生并不被方法外部可访问的数据都是私有数据,多线程编程称为线程安全。相反线程不安全。

Java 虚拟机规范定义了 Java 内存模型来屏蔽掉各种硬件和操作系统的内存差异,达到跨平台的内存访问效果。

为了获得更好的执行性能,Java 内存模型没有限制执行引擎使用处理器的特定缓存器或缓存来和主内存(可以和 RAM类比,但是是虚拟机内存的一部分)交互,工作内存 (可类比高速缓存,也是虚拟机内存的一部分) 为线程私有。

工作内存和主内存的划分和 Java 堆,栈,方法区的划分不同,两者基本没有关系,如果勉强对应,则主内存可理 解为堆中实例数据部分,工作内存则对应栈中部分区域

–引用 «深入理解 JAVA 虚拟机»

线程栈 Execution stack

每个线程都有一个线程栈,线程的每个方法被执行的时候,都会同时创建一个帧 (Frame) 用于存储 本地变量表、操作栈、动态链接、方法出入口等信息。每一个方法的调用至完成,就意味着一个帧在VM栈中的入栈至出栈的过程。如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果VM栈可以动态扩展 (VM Spec中允许固定长度的VM栈) ,当扩展时无法申请到足够内存则抛出 OutOfMemoryError异常。

一个栈帧又分为: 局部变量区、操作数栈和帧数据区。你可以理解 工作内存为局部变量区中的数据。

https://segmentfault.com/q/1010000004885908

https://www.oschina.net/question/1779843_2163094