自动垃圾收集器
自动垃圾收集器是查看堆内存,识别正在使用那些对象以及那些对象未被删除以及删除未使用对象的过程。
使用中的对象或引用的对象意味着程序的某些部分仍然维护指向对象的指针。
程序的任何部分都不再引用未使用的对象或者引用的对象,因此可以回收未引用对象使用的内存。
像C这样的编程语言中,分配和释放内存是一个手动过程。
在Java中,解除分配内存的过程由垃圾收集器自动处理
如何确定内存需要被回收
程序计数器没办法解决循环应用问题
可达性分析算法
强引用和可达性级别
引用类型
- 强引用(StrongReference):最常见的普通对象引用,只要强引用指向一个对象,就不会回收。
- 软引用(SoftReference):JVM认为内存不足时,才会去视图回收软引用指向的对象。(缓存场景)
- 弱引用(WeakReference):虽然是引用,但随时可能被回收掉
- 虚引用(PhantomReference):不能通过它访问对象。共了对象被finalize以后,执行指定逻辑的机制(Cleaner)
可达性级别
- 强可达(Strongly Reachable):一个对象可以有一个或多个线程可以不通过各种引用访问到的情况。
- 软可达(Softly Reachable):就是当我们只能通过软引用才能访问到对象的状态
- 弱引用(Weakly Reachable):只能通过弱引用访问时的状态。当弱引用被清楚的时候,就符合销毁条件。
- 幻想可达(Phantom Reachable):不存在其他引用,并且finalize过了,只有幻想引用指向这个对象。
- 不可达(unreacheable):以为着对象被清除了。
垃圾回收算法
-
标记-清除(Mark-Sweep)算法:首先标识出所有要回收的对象,然后进行清除。
标记、清除过程效率有限,有内存碎片问题,不适合特别大的堆;收集算法基本基于标记-清除的思路进行改进
-
复制(Copying)算法:划分两块同等大小的区域,收集时将或者的对象复制到另一块区域。
拷贝过程中对象顺序防止,就可以避免内存碎片化。复制+预留内存,有一定的浪费。
-
标记-整理(Mark-Compact)算法:类似于标记-请出,但为了避免内存碎片化,它会在清理过程将对象移动,以确保移动后的对象占用连续的内存空间。
标记清除
回收完,剩余两个 8字节,但是要存大对象16字节,是没办法存的。这就是所谓的内存碎片比较验证。
分代收集
垃圾收集器
启动一个线程 进行垃圾收集
具体的信息可参看《深入理解Java虚拟机JVM高级特性与最佳实践》
- Serial收集器
- ParNew收集器
- Parallel Scavenge收集器
- Serial Old收集器
- Parallel Old收集器
- CMS收集器
- G1垃圾收集器
垃圾收集器组合