标记算法

引用计数算法(不适合循环引用)

  1. 通过判断对象的引用数量来决定对象是否可以被回收
  2. 每个对象实例都有一个引用计数器,被引用则+1,完成引用则-1
  3. 任何引用计数为0的对象实例可以被当做垃圾收集

优点: 执行效率高,程序执行受影响较小

缺点: 无法检测出循环引用的情况,导致内存泄露

可达性分析算法

通过判断对象的引用链是否可达来决定对象是否可以被回收

可以作为GCRoot的对象

垃圾回收算法

标记-清除算法(碎片化)

  • 标记:从根集合进行扫描,对存货的对象进行标记
  • 清除:对堆内存从头到尾进行线性遍历,回收不可达对象

缺点:不需要进行对象的移动,碎片化严重。如果下一次需要新建一个大的对象,位置不够

复制算法(年轻代)

  • 分为对象面和空闲面
  • 对象在对象面上创建,存活对象从对象面复制到空闲面,再将对象面的所有对象清除

  • 解决了碎片化问题
  • 顺序分配内存,简单高效
  • 适用于对象存活率低的场景
  • 适用于年轻代(存活对象少)

标记-整理算法(老年代)

  • 标记:从根集合进行扫描,对存货的对象进行标记
  • 清除:移动所有存活的对象,且按照内存地址依次排列,然后将末端内存地址以后的内存全部回收

  • 避免内存的不连续
  • 不用设置两块内存互换
  • 适用于存活率高的场景,如老年代

分代收集算法

  • 垃圾回收算法的组合拳
  • 按照对象生命周期的不同划分区域采用不同的垃圾回收算法
  • 目的:提高JVM的回收效率

GC的分类

  • Minor GC

发生在年轻代,采用复制算法

  • Full GC

与老年代相关,一般老年代的回收伴随着年轻代的回收,因此称为FullGC

年轻代:尽可能快速地收集掉那些生命周期短的对象

  • Eden区(伊甸园)
  • 两个Survivor区(from&to)
    8:1:1

年轻代垃圾回收过程:


eden满了,触发mirror-gc,将存活对象复制到survivor


清理eden区


eden再次满了,将eden和s0中的对象拷贝到s1,年龄加1,清理eden和s0


eden再次满了,将eden和s1中的对象拷贝到s0,年龄加1,清理eden和s1

当对象的年龄超过一定岁数,变为老年代,可通过参数调节

对象如何晋升到老年代

  • 经历一定Minor次数仍然存活
  • Survivor区中放不下的对象
  • 新生成的大对象(-XX:+PretenuerSizeThreshold)

常用调优参数

老年代:存放生命周期较长的对象

大概比例1:2

  • FullGC和MajorGC
  • FullGC比MinorGC慢(10倍),但执行频率低

触发fullGC方条件:

  • 老年代空间不足

  • MinorGC晋升到老年代的平均大小大于老年代的剩余空间

  • 永久代空间不足(JDK7之前,这也是用元空间替代永久代的原因,降低fullGC的频率)

  • 调用System.gc()(这个方法不一定执行)

  • CMS GC时出现promotion failed,concurrent mode failure

  • 使用RMI来进行RPC或者管理的JDK应用,每小时执行一次FullGC

垃圾收集器

  • stop-the-world

  • Safepoint(回收垃圾要提醒不要扔垃圾)

  • JVM的运行模式
  1. Server(启动慢,稳定后比Client快)
  2. Client

垃圾收集器的联系

年轻代常见收集器


除了Serial只有它能和CMS配合,Server下的首选的收集器

老年代常见收集器

对停顿不敏感,硬件好,更多存活时间长的对象选择CMS;碎片化

GC常见面试题

Object的finalize()方法的作用是否与C++的析构函数作用相同

1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String[] args) {
Finalization f = new Finalization();
System.out.println("First print: " + f);
f = null;
System.gc();
try {// 休息一段时间,让上面的垃圾回收线程执行完成
Thread.currentThread().sleep(1000);
} catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("Second print: " + f);
System.out.println(f.finalization);
}

java中的强引用,软引用,弱引用,虚引用有什么用

强引用

软引用

弱引用

虚引用

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×