Java 垃圾回收
回收区域:java堆
对象划分:
- 新生代内存(Young Generation)
- 老生代(Old Generation)
- 永久代(Permanent Generation)
永久代和原空间的区别在于元空间在直接内存上。
堆的结构如上图所示。Eden, s0, s1为新生代,Tenured 为老年代, 最底下是永久代。
内存分配规则
一般新对象会分配到Eden区域,当Eden满时,触发GC(垃圾回收)
大对象和长期存活的对象分配到老年代。
如何判断对象死亡
引用计数法
缺点 循环引用
每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;
任何时候计数器为 0 的对象就是不可能再被使用的。
可达性分析
从GC root出发,标记所有可以到达的对象,未被标记到的可作为回收对象。GC root包括
虚拟机栈(栈帧中的本地变量表)中引用的对象
本地方法栈(Native 方法)中引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象
所有被同步锁持有的对象
垃圾收集算法
标记-清除 (会有碎片问题)
标记-复制 (两块内存,不适合大对象)
标记-整理 (适合大对象)
分代算法 (结合不同对象来选择上述的算法)
垃圾收集器
Serial 收集器(单线程 新生代 标记-复制,老年代 标记整理)
ParNew 收集器(多线程 新生代 标记-复制,老年代 标记整理)
Parallel Scavenge 收集器 (多线程 吞吐量高 新生代 标记-复制,老年代 标记整理)
XX-Old收集器则是XX收集器处理老年代版本。
CMS 收集器 (优化用户感知时间,停顿小, 标记-清除)
G1 收集器 (结合CMS, Parallel的优点 )
将Java堆划分为多个大小相等的区域,并采用类似于新生代的复制算法来处理Eden区和Survivor区,同时使用标记-整理算法来回收Old区。