jvm之GC知识点
一、GCRoots:
-
虚拟机栈(栈帧中的局部变量表)引用的对象
-
方法区中静态属性引用的对象
-
方法去中常量引用的对象
-
本地方法栈中JNI(NATIVE方法)引用的对象
二、引用:
reference类型数据中存储着另外一块地址的起始地址
-
强引用:通常的引用,只要引用存在便不会被回收
-
软引用:有用但非必需的对象,在内存将要发生内存溢出异常时,会将这些对象列入范围,进行二次回收。
-
弱引用:非必需对象,只能生存到下次回收之前,无论内存充足与否,都会被回收。
-
虚引用:对生存无影响,无法通过虚引用获得对象实例,为一个对象设置虚引用关联的目的是在这个对象被回收之前收到一个系统通知。
三、标记死亡:
-
可达性分析筛选对象
-
是否有必要执行finallize()方法(有没有覆盖finallize方法,是否已由虚拟机调用)
-
F-Queue队列(由虚拟机建立,低优先级的Finallize线程执行(触发 finallize() 方法,不等待完成(防止finallize方法阻塞)))
-
-
等待回收
四、方法区回收:
-
效率低,回收很少
-
废弃常量:
-
无用的类:
-
该类所有的实例都被回收,java堆中不存在该类的实例。
-
加载该类的classloader()已经被回收。
-
该类对应的java.lang.Class对象没有在任何对象中被引用,无法在任何地方通过反射访问该类的方法。
-
五、引用计数法:
-
可达性分析判定对象存活。
六、回收算法:
-
标记-清除:标记所有需要回收的对象,然后回收。效率低,空间碎片问题
-
复制算法:将内存花费为等大小两块儿,每次只使用一块儿,当一块儿用完,将所有还存活的对象复制到另一块儿,然后把使用过的内存空间一次性清理掉。
-
-
实现简单,运行高效;空间浪费;对象存活率较高时,效率低;
-
-
标记整理(老年代):
-
-
标记可回收对象=》所有可存活对象向内存一端移动=》清理边界外的内存。
-
- 分代回收:
-
-
如年轻代的复制算法,老年代的标记清除,或者标记整理算法。
-
七、HotSpot虚拟机:
-
GC Roots枚举:在安全点通过ooPMap引用表进行枚举,
-
安全点:方法调用,循环跳转,异常跳转产生安全点=》进入GC
-
安全区域:处理不执行的程序
八、垃圾收集器:
-
Serial
-
-
New:Client模式下新生代默认收集器,根据回收内存的大小,简单而高效
-
Old:主要用在Client模式下老年代收集,
-
-
Parallel
-
-
Serial的对线程版本。
-
New:Server模式下新生代默认的收集器,默认搭配老年代CMS收集器,默认开启线程数=CPU个数。
-
Scavenge:新生代收集器,复制算法,吞吐量优先。-XX:UserAdaptiveSizePolicy 自适应
-
Old:Scavenge的老年代版本收集器。标记-整理算法
-
- CMS: Concurrent Mark Sweep 并发收集 低停顿,默认线程数 (cpu数 + 3)/4
-
-
初始标记=》并发标记=》重新标记=》并发清理
-
cpu资源敏感(线程数 并发处理过程影响)
-
无法处理浮动垃圾(并发阶段用户线程产生的垃圾)
-
标记-清除回收算法产生空间碎片:
-
+UseCMSCompactAtFullCollection(默认开启)Full GC时 compact
-
+UseCMSFullGCsBeforeCompact(默认0)执行compact的FullGC间隔。
-
-
- G1:服务端收集器
-
-
并行与并发
-
分代收集:
-
空间整合:整体 标记-整理 算法,局部(region)复制算法,避免空间碎片
-
可预测的停顿:预测时间模型
-
九、吞吐量:
-
运行用户代码的时间/(运行用户代码时间+垃圾回收时间)
十、jvm内存管理:
分配内存+回收内存
-
大对象:需要大量连续空间的java对象(如:字符串,数组)
-
对象优先在Eden区分配
-
大对象直接进入老年代 -XX:PretenureSizeThreshod 直接进入老年去的大对象阈值。避免新生代去的大量复制
-
对象年龄计数器(Age),MinorGC之后进入Survivor区(Age=1),每经一次MinorGC,Age+1,达到-XX:MaxTenuringThreshod后,或者Survivor存活量大于一半,进入老年代。