概述
这篇文章是我学习周志明大大《深入理解Java虚拟机》内存管理章节的学习笔记.
运行时内存模型
- 程序计数器
- 虚拟机栈
- 本地方法栈
- 方法区(永久代)
- 堆(年轻代和老年代)
- 直接内存(NIO堆外内存)
内存分配比例
- 年轻代一般占三到五分之一;
- 永久代在32位JDK默认64M, 在64位JDK默认85M, 我们可以设置大一点,128M,256M
- JDK8 没有永久代, 替换为MetaSpace, MetaSpace是Native Memory, 大小限制取决于系统内存大小
程序计数器
- 程序计数器记录下一条需要执行的指令,分支, 循环, 跳转, 异常处理, 线程回复依赖此计数器
- 程序计数器是线程私有的空间
- 虚拟机执行Native方法时,计数器为空
- 此区域没有规定任何OutOfMemoryError异常
虚拟机栈
虚拟机栈是Java方法执行的内存模型, 每个方法调用同时创建一个栈帧. 栈帧保存了局部变量表, 操作数栈, 动态链接, 方法出口等信息.
局部变量表所需的空间在编译时确定. 64位的long和double占用2个局部变量空间(slot), 其他数据类型占用1个(包含reference类型).
- 虚拟机栈是线程私有的空间
- 此区域规定了OutOfMemoryError和StackOverFlowError
本地方法栈
此内存区域和虚拟机栈功能相似, 只是虚拟机栈用来执行Java code, 本地方法栈是为虚拟机使用的Native方法服务.
虚拟机栈可能和本地方法栈合二为一(如: Oracle Hotspot虚拟机).
方法区
- 用于存储加载的类信息, 常量, 静态变量, JIT编译后的代码数据.
- JVM描述此区域为堆的一部分.
- JVM规范对方法区限制宽松, 可以选择不实现垃圾回收(所以叫永久代).
- 此区域的回收目标是对常量池的回收和类型的卸载.
常量池
- 用于存放编译期生成的字面量和符号引用(直接引用也会放到常量池).这部分内容在类加载后存放到常量池.
- 常量池具备动态性.常量不一定在编译器产生, 运行时也可以将常量放入常量池(如: String的intern() 方法).
- 并不是声明了为final的变量都会进入常量池
堆
此区域的唯一目的是存放对象实例. 但并不是所有对象实例都在堆上分配.有栈上分配,标量替换等优化技术.
堆可以划分为 新生代和老年代. 新生代可分为Eden , Survivor , to区(一般比例为8:1:1).
堆内存可以不连续, 逻辑上连续即可.
直接内存
- NIO库中可以使用.
- 直接内存并不是JVM运行时数据区的一部分.
- 此区域规定了OutOfMemoryError异常.
内存回收
对象死亡判定
- 引用计数器
- GC ROOT算法
垃圾回收算法
- 标记-清除法(最基本的)
- 标记-复制法
- 标记-整理
一般来说, 年轻代使用标记-复制法, 老年代使用标记整理法
垃圾收集器
收集器 | 说明 |
---|---|
Serial | 使用单线程进行垃圾收集 2. 垃圾收集工作时, 暂停所有工作线程 3.暂停时间不可控制 |
Serial Old | Serial收集器的老年代版本 |
ParNew | Serial收集器的多线程版本, 在多CPU下,效率更高, 单CPU就不如Serial, 毕竟会增加线程切换开销. |
Parallel Scavenge | 新生代收集器 2. 关注吞吐量. 吞吐量 = 用户代码运行时间/(用户代码运行时间 + 垃圾收集时间). 吞吐量的值通过-XX:MaxGCPausemills和-XX:GCTimeRatio参数控制. |
Parallel Old | Parallel Scavenge老年代版本. |
CMS (Concurrent Marked Sweep) | 基于标记-清除算法 2. 过程是-初始标记-并发标记-重新标记-并发清除 3. 缺点是对CPU资源敏感, 无法处理浮动垃圾, 基于标记清除算法, 容易产生内存碎片 |
G1 | 基于标记-整理算法 2. 可以精确控制停顿时间 3. 原理是将堆分为多个Region,维护一个列表记录垃圾堆积程度, 根据设定的停顿时间,优先回收垃圾最多的区域(Garbage First). |
内存分配策略
- 对象优先在Eden分配
- 大对象(长字符串和大数组)直接进入老年代(所以程序中出现大量朝生夕死的大对象非常可怕).
- 长期存活的对象直接进入老年代, 通过-XX: MaxTenuringThreshold参数控制, 默认值为15.
- 动态年龄判定(并不是一定要达到某个年龄才可以进入老年代,如果Suvivor空间中相同年龄所有对象的大小总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代.)
- 空间分配担保