一. 内存模型
类装载子系统根据全限定名将类文件转载至运行时数据区, 由执行引擎执行.
内存中分为五大区:堆、栈、方法区、本地方法栈、程序计数器。
- 方法区(1.8后为元数据区):主要是存放已加载的方法信息、类信息、常量池、静态变量, 可通过-XX:PermSize和-XX:MaxPermSize来指定持久带初始化值和最大值
- 堆: 类的实例化对象和定义的数组
二. JVM运行时数据区
JVM运行时内存 = 共享内存区 + 线程内存区
共享内存区
- 共享内存区 = 持久带(Permanent Space) + 堆
- 持久带 = 方法区 + 其它
- 堆 = 老年带 + 年轻代(年轻代=Eden+S0+S1)
老年带存放生命周期长的存活对象, 年轻代的S0/S1是两个大小相等的内存区域, 主要存放对象从S0/S1通过Eden过度到老年带。堆之所以要划分区间,是为了方便对象创建和垃圾回收。
线程内存区
- 线程内存区 = 单个线程内存+单个线程内存+.......
- 单个线程内存 = 栈 + 程序计数器 + 本地方法区
- 栈(JVM栈) = 栈帧+栈帧+.....
- 栈帧 = 局部变量 + 操作数区 + 栈数据区
在Java中,一个线程会对应一个JVM栈(JVM Stack),JVM栈里记录了线程的运行状态。JVM栈以栈帧为单位组成,一个栈帧代表一个方法调用。
线程在栈区, 不能共享数据, 只能通过复制共享区的数据作为一块缓存, 所以多线程容易存在BUG, voliate使得取到的数据不做缓存, 是实时更新的,具有可见性和有序性, 原子性则需要Atomic类来解决。