文章目录
1、JVM堆内存分代模型
- 年轻代:对象创建之后很快就可以被回收。例如方法局部变量引用的对象,很可能方法调用结束后就没人引用了。
- 老年代:对象是需要长期存在的。例如静态变量所引用的对象,它会随着Jvm的销毁而销毁,也就是整个生命周期都是存活的。
- 永久代:存放类的一些信息,生命周期较长,大部分随着Jvm的销毁而销毁。
2、年轻代、老年代、永久代垃圾回收机制?
- 年轻代:
A) 大部分对象会优先在年轻代分配内存
B) 当给一个新对象分配内存时,发现新生代内存不够分配时,会触发新生代的垃圾回收。 - 老年代:
A) 新生代垃圾回收后,存活对象过多进入老年代
B) 躲过默认15次Young Gc的对象会进入老年代
C) 大对象(默认1M)创建时会直接进入老年代
D) 空间担保机制 - 永久代:
A) 该类的实例对象已经在JAVA堆内被回收
B) 加载该类的ClassLoader已经被回收
C) 该类的Class对象没有任何引用
3、哪些对象不会被垃圾回收期回收
- JVM使用了可达性分析算法来判定对象是否可以被回收:对于每个对象,一层层往上判定,看是否有一个GC Roots在引用它
- 类的静态变量、方法的局部变量可以看做是GC Roots
- 简单来说,一个对象只要被类的静态变量以及方法的局部变量所引用,那么该对象就无法被回收
4、JVM核心参数
- -Xms: 最小堆内存
- -Xmx: 最大堆内存
- -Xmn: 堆新生代大小
- -XX:PermSize: 永久代大小
- -XX:MaxPermSize: 最大永久代
- -Xss: 每个线程栈大小
5、Java对象不同的引用类型的垃圾回收
- 强引用:例如类静态变量引用的对象,垃圾回收器不会回收此种对象
- 软引用:被SoftReference<>软引用类型包裹的对象,垃圾回收器会在堆内存不足分配给新对象(即将 内存溢出)时进行回收
- 弱引用:被WeakReference<>弱引用类型包裹的对象,垃圾回收器会在下一次垃圾回收时回收此种对象
- 虚引用:很少用,可忽略
6、逃脱垃圾回收的最后一次机会finalize()
- 调用时机:当垃圾回收器要宣告一个对象死亡时,至少要经过两次标记过程:如果对象在进行可达性分析后发现没有和GC Roots相连接的引用链,就会被第一次标记,并且判断是否执行finalize( )方法,如果对象覆盖finalize( )方法且未被虚拟机调用过,那么这个对象会被放置在F-Queue队列中,并在稍后由一个虚拟机自动建立的低优先级的Finalizer线程区执行触发finalize( )方法,但不承诺等待其运行结束。
- 目的:对象逃脱死亡的最后一次机会。假如对象重写了它的finalize()方法并把自己的实例赋给其它的GC Roots,那么该对象在垃圾回收时不会被回收。
7、小结
本文简单介绍了JVM堆内存的分代模型以及相对应的垃圾回收时机(比较粗糙,后面详细介绍)、程序运行时JVM核心参数、Java对象不同引用类型的垃圾回收、哪些对象不会被垃圾回收、以及逃脱垃圾回收的最后一次机会。