JVM的自动内存管理主要是进行对象内存的分配和回收,最核心的功能是堆内存中对象的分配和回收,。堆是垃圾手机管理的主要区域。
如何判断对象可被GC回收:
引用计数算法:
给对象添加一个计数器,当有地方引用它时,计数器就+1,当有一个引用失效的时候,计数器就-1.
弊端:对象循环引用,若a指向b,且b指向a,则引用计数算法就无法回收它们。
根可达性算法:
定义一系列的根,主根称为GC Roots,从GC Roots开始向下搜索,查找的路径把它称为“引用链”,当一个对象和GC Roots没有引用链相连时,那它被当成垃圾回收了。
java的四种引用类型:
强引用:不管内存空间如何们都不会被回收。弱化强引用的方法(1:给弱化的对象赋值为空。2:让对象超出作用域范围)。
软引用:当内存空间足够时,它不会被回收,当内存空间不足时,就被垃圾回收器回收。(软引用可以实现内存敏感的高速缓存)。
弱引用:不管内存空间如何,都被垃圾回收器回收。
虚引用:如果一个对象仅仅持有虚引用,那它就和没有任何引用一样,会随时被回收。
垃圾收集算法:
标记-清除算法:先标记所有不需要回收的对象,标记完成后,回收所有未被标记的对象(弊端:效率低,空间问题(标记清除后会产生大量不连续的碎片))
标记-赋值算法:把内存分为两个相等的空间,用其中的一块且使用完后,把还存活的对象复制到另外一块去,再把第一个空间清理掉(弊端:浪费空间,使现有的空间变为原来的一半)
标记-整理算法:先进行标记,再把存活的对象向内存空间任意一端移动,然后清理边界以外的内存。
垃圾收集器:
Serial(新生代):是一个单线程收集器,当它收集垃圾时,其他所有的线程都必须停止,它采用标记-复制算法进行垃圾收集。
Serial Old(老年代):是一个单线程收集器,采用标记-整理算法收集。
ParNew(新生代):一个多线程收集器,新生代采用标记-复制算法,老年代采用标记-整理算法。
Parallerl Scavenge(新生代):多线程收集器,采用标记-复制算法,它的关注点是高效率的利用CPU,停顿时间越短就越适合需要与用户交互的程序,良好的响应速度能提升用户体验,高吞吐量则可以高效率的利用cpu时间,尽快完成程序的运算任务吗,,适合在后台运算不需要太多交互的任务。
Parallel Old(老年代):是一个多线程收集器,采用标记-整理算法。
CMS(老年代):并发收集器,采用标记-清除算法,(初始标记、并发标记、重新标记、并发清除).优点:并发收集,低停顿。缺点:影响用户线程的执行效率、无法处理浮动垃圾、产生大量空间碎片。
G1(老年代):面向服务器的垃圾收集器,主要针对配备多颗处理器,大容量内存的机器。(流程:初始标记、关联到的对象、并发标记、达性分析、最终标记、筛选回收、),特点:并发与并行、分代收集、空间整合、可预测的停顿。