JAVA虚拟机学习笔记之垃圾回收

一、对象存活判断
1、引用计数算法,无法解决对象之间循环引用问题,虚拟机中没有采用
2、可达性分析算法,以GC Roots为起点,搜索引用链(Reference Chain),无任何引用链相连的对象为不可达
3、GC Roots对象包括4中,虚拟机栈(变量表)中引用的对象,方法区类静态属性引用对象,方法区常量表引用的对象,本地方法栈中JNI引

用的对象

二、对象引用分类
1、强引用(Strong Reference),垃圾回收器不回收
2、软引用(Soft Reference),内存不足时垃圾回收器回收,应用场景图片编辑器缓存图片
3、弱引用(Weak Reference),下次垃圾回收时回收,应用场景WeakHashMap中的key,也可以通过Collections.newSetFromMap得到一个

WeakHashSet
4、虚引用(Phantom Reference),不影响垃圾回收,加入引用队列仅为垃圾回收时发送通知,应用少见,可以用于移动端做精细内存控制

三、回收过程
1、通过可达性分析找到没有与GC Roots引用链的对象,加入可回收集合
2、判断对象是否需要执行finalize()(覆盖finalize()方法且虚拟机没调用finalize()),需要执行则加入F-Queue等待Finalize线程执行
3、finalize()调用过程中,对象重新建立引用可以逃脱回收
4、执行回收

四、方法区垃圾回收
1、方法区垃圾回收分为两部分:废弃常量和无用的类
2、废弃常量定义:没有任何引用的常量
3、无用类定义:该类所有实例已回收,加载该类的ClassLoader已回收,该类对应的java.lang.Class没有任何引用
4、满足条件的无用类可以被虚拟机回收,是否回收取决于参数配置-Xnoclassgc

五、垃圾回收算法
1、标记清除算法(Mark-Sweep),缺点是效率不高,产生大量不连续碎片
2、复制算法(Copying),缺点是浪费空间,商业虚拟机用此算法管理新生代,因为新生代98%对象朝生夕死,内存分为一块大Eden、两块小

survivor,垃圾收集时将Eden和当前survivor复制到另一块survivor,默认空间比例8:1:1,当剩余对象超过空间10%时,依赖老年代内存
3、标记处理算法(Mark-Compact),与标记清除算法类似,但不复制清理,而是让存活对象向一边移动,然后清理边界以外是内存,适合存活

率较高的老年代
4、分代搜集算法(Generational Collections),将内存分为新生代、老年代分别管理,各自采用合适的垃圾收集算法

六、垃圾收集器
1、Serial收集器,新生代收集器,单线程,对Client模式下的虚拟机来说是一个很好的选择
2、ParNew收集器,新生代收集器,Serial的多线程版本,适合Server模式下的虚拟机,唯一可以和CMS配合工作的收集器
3、Parallel Scavenge收集器,新生代收集器,关注吞吐量,而非停顿时间,提升CPU使用效率,适合在后台运算而不需要太多交互的任务
4、Serial Old收集器,老年代收集器,Serial的老年代版本,适合client模式,在server模式可适合与Parallel Scavenge搭配或者作为CMS

的备用收集器
5、CMS收集器,老年代收集器,一种以获取最短回收停顿时间为目标的收集器,适合互联网站或者B/S系统的服务端
6、G1收集器,分区收集器,通过维护优先列表,优先回收价值最大的Region

七、内存分配回收策略
1、对象优先在新生代Eden上分配(如果启动TLAB,则优先在TLAB上分配)
2、大对象之间进入老年代,可通过-XX:PretenureSizeThreshold设置大小
3、长期存活对象进入老年代(通过age计数器,一次Minor GC加1,默认15进入老年代)
4、动态判断对象年龄,如果survivor空间中相同年龄所有对象大小总和大于survivor空间一半,大于等于该年龄的对象直接进入老年代
5、空间分配担保,只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小就会进行Minor GC,否则进行Full GC

/*
	 * vm args -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
	 * 直接分配老年代对象大小 -XX:PretenureSizeThreshold=3145728
	 * jdk1.7指定Serial收集器才能使PretenureSizeThreshold生效 -XX:+UseSerialGC
	 */
	private static void doMemoryAllocation() {
		byte[] a1, a2, a3, a4;
		a1 = new byte[2 * 1024 * 1024]; 
		a2 = new byte[2 * 1024 * 1024];
		a3 = new byte[2 * 1024 * 1024];
		a4 = new byte[4 * 1024 * 1024];
	}
	
	/* 
	 *  -XX:PretenureSizeThreshold=100000
	 * 直接分配老年代对象大小 -XX:PretenureSizeThreshold=3145728
	 * jdk1.7指定Serial收集器才能使PretenureSizeThreshold生效 -XX:+UseSerialGC
	 */
	private static void doBigObjAllocation() {
		 byte[] allocation1 = new byte[1 * 1024 * 1024]; 
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值