1. 内存区域
程序计数器
保存当前正在执行的程序的内存地址。
JAVA是多线程的,被中断的线程当前执行到哪条内存地址是需要保存下来的。每个线程都有一个独立的程序计数器,互相独立,线程私有。
可以理解为当前线程所执行的字节码行号指示器。字节码解释器工作时就是通过改变计数器的值来选取下一条字节码指令,分支、循环、跳转、异常处理、线程恢复等功能都需要依赖这个计数器来完成。
栈
栈与线程对应,每创建一个线程,JVM就会为其创建一个栈。
栈里面的元素是栈帧,栈帧与方法对应,每当运行一个方法时就创建一个栈帧,入栈,方法执行完成,栈帧出栈。
栈帧中包括:局部变量表、操作数栈、动态链接方法、返回地址。
栈顶的栈帧是当前正在执行的活动栈,程序计数器会指向这个地址。
堆
堆存放所有的对象和数组,是所有线程共享的区域,非线程安全。
堆是JVM管理的内存中最大的一块,是GC垃圾收集的区域。
方法区
方法区中存放类信息、类中静态常量、final常量、类的field信息、类的方法信息。
方法区其实是堆中的一个部分,就是堆中的永久区。
本地方法栈
作用和上面说的栈类似,区别就是服务对象不同,java栈为JVN执行java方法服务,本地方法栈为JVM执行Native方法服务。
2. 主内存与工作内存
所有变量都保存在主内存中,每个线程有自己的工作内存,保存该线程用到的变量,工作内存中的变量是主内存中变量的副本。
线程对变量的读写操作都是在工作内存中完成,而不是直接在主内存中操作。
当线程操作某个对象时,执行顺序如下:
- 从主存复制变量到当前工作内存 (read,load)
- 执行代码,改变共享变量值 (use,assign)
- 用工作内存数据刷新主存相关内容 (store,write)
volatile 关键字保证了多线程内存可见性,使用 volatile 修饰的变量都不拷贝副本到工作内存,任何修改都及时在主内存中操作,所有线程可以马上看到,但volatile不能保证对变量的修改是有序的。
网友评论