[技术向] 高级语言特性 (Java)
JMM
Java 内存模型 (JMM) 是在并发的视角下, 对程序执行的一种规范, 规定了一个线程的写操作何时对另一个线程可见, 规范就是一种抽象, 目的是提供对跨平台的良好支持.
JMM 规定, 共享变量都存储在主内存中, 每个线程有自己的工作内存, 用以保存局部变量和主内存的副本拷贝, 线程对共享变量的操作在工作内存中进行, 不能直接读写主内存中的变量. 工作内存中的副本变化会遵循某种策略刷新到主内存中.
主内存和工作内存的交互有 8 种同步操作 (Lock/Unlock/Read/Write/Store/Load/Use/Assign).
JVM
JVM 把内存分为线程私有和线程共享两个区域, 前者包括每个线程的程序计数器 (PC)、方法栈等, 后者包括堆和元空间. 堆 (Heap) 又分成新生代和老年代, 分别存放"朝生夕死"和"长期使用"的对象. 元空间用于记录各个类的元信息, 包括类的结构、方法的字节码、注解等.
我们知道, 在大型 Java 程序运行的过程中, 性能瓶颈很大程度上与垃圾回收有关.
这里重点关注现代 JVM 的垃圾回收机制 (相关概念可见 虚拟内存).
垃圾收集
类加载
原生并发机制
volatile
保证变量可见性, 使用了 MESI 协议, 通过总线嗅探机制实现.
MESI 是支持写回策略的缓存一致性协议, M, E, S, I 分别代表一个缓存行的四种状态:修改过 (Modified)、独占 (Exclusive)、共享 (Shared)、无效 (Invalid), 当一个缓存行被标记为 M 时, 在其他缓存中的数据副本会被标记为 I, 当缓存不命中且数据在另一个缓存中有效时, 允许缓存到缓存的数据复制.
保证有序性, 禁止指令重排序.
synchronize
被包裹的代码块在编译时会插入 monitorenter 和 monitorexit 两个字节码指令.