JVM GC回收机制

JVM GC 系统 面试问题

  1. 市场常见GC算法?(不限于java平台)
  2. JVM中常见GC算法?(不同规范的实现,算法不相同)
  3. JVM规范的实现HotSpot虚拟机有什么GC算法的应用?具体应用场景有什么不同。

FAQ:

1.当对象存在引用时,是否可能在系统触发GC时被回收?可能,要看引用类型?
2. 当GC系统没有启动,对象是否可能被回收?
3.当GC系统触发时,假如对象要被销毁了会执行finalize方法吗?会的。

1)当对象存在引用时,是否可能在系统触发GC时被回收?
	答:
	1. 可能,要看引用类型;
    2. 强引用不会,软引用在内存不足时会,弱引用会被回收,虚也会。
    3. 在JAVA中我们可以使用的对象引用方式有四种:
		1)强引用:此引用引用的对象,生命力最强。(对象不会被GC)
		2)软引用:此引用引用的对象,在内存不足时可能会被GC。
		3)弱引用:此引用引用的对象,在GC执行时可能直接会被销毁(即便是内存充足)。
		4)虚引用:用的最少,类似没有引用,主要用于记录对象的销毁。---了解
		***说明:软引用和弱引用通常会应用在一些缓存产品的设计中。***

代码案例

package com.cy.java.jvm.gc;

import java.lang.ref.WeakReference;

/**
 * FAQ:
 * 1)当对象存在引用时,是否可能在系统触发GC时被回收?可能,要看引用类型?
 * 2)当GC系统触发时,假如对象要被销毁了会执行finalize方法吗?会的。
 * 
 * JVM GC 系统
 * 1)市场常见GC算法?(不限于java平台)
 * 2)JVM中常见GC算法?(不同规范的实现,算法不相同)
 * 3)JVM规范的实现HotSpot虚拟机有什么GC算法的应用?具体应用场景有什么不同。
 */
class Container{
	private Object[] array;
	public Container(int cap) {
		this.array=new Container[cap];
	}
	//....
	@Override
	protected void finalize() throws Throwable {
		System.out.println("==finalize()==");
	}
}
public class TestGC02 {

    public static void main(String[] args) {
    	doMethod01();
	}
	/**
	 * 在JAVA中我们可以使用的对象引用方式有四种:
	 * 1)强引用:此引用引用的对象,生命力最强。(对象不会被GC)
	 * 2)软引用:此引用引用的对象,在内存不足时可能会被GC。
	 * 3)弱引用:此引用引用的对象,在GC执行时可能直接会被销毁(即便是内存充足)。
	 * 4)虚引用:用的最少,类似没有引用,主要用于记录对象的销毁。---了解
	 * 
	 * 说明:软引用和弱引用通常会应用在一些缓存产品的设计中。
	 */
	private static void doMethod01() {
		//1.强引用
    	Container c1=new Container(100);//c1就是强引用
    	c1=null;//此时c1指向的Container对象不可达(也就是说JVM访问不到了)
    	//2.软引用
    	SoftReference<Container> c2=new SoftReference<Container>(new Container(20));
    	Container cc=c2.get();//这种写发是又将软引用转换为了强引用。不推荐
    	System.out.println(c2.get());//通过软引用获取和操作对象
    	//3.弱引用
    	WeakReference<Container> c3=new WeakReference<Container>(new Container(100));
    	System.out.println(c3.get());
    	
    	//手动GC
    	System.gc();//GC启动以后,GC系统会对内存中的对象进行可达性分析。访问不到则进行标记。
    	//自动GC(通过JVM参数进行分析)
//    	List<byte[]> list=new ArrayList<>();
//    	for(int i=0;i<100000;i++) {
//    		list.add(new byte[1024*1024]);
//    	}
	}
}
2)当GC系统没有启动,对象是否可能被回收?
    
     答:
      1. 可能,要看对象分配在哪,栈中不用GC,直接回收
      2. Java中大多数对象都会存储在堆(heap)中,但对于一些没有逃逸的小对象,现在也可能分配在栈上(JVM发展历程中的一种新的优化方式),
      3. 小对象,未逃逸(方法外界没有引用指向方法内对象),栈上直接销毁,不用GC
      4. 小对象,逃逸(方法外界有引用指向方法内对象),分配在堆上
    
    JDK8中,默认打开逃逸分析选项,希望未逃逸的小对象分配在栈上,这样可以避免启动GC进行回收对象。

	总结:
	小对象,未逃逸,栈上分配(方法调用结束,对象销毁,不需要借助GC); 
	小对象,已逃逸,堆上分配(对象回收需要借用GC系统);

代码案例:

package com.cy.java.jvm.gc;
/**
 * 当GC系统没有启动时,对象是否可能被回收?可能,看你对象分配在哪了?
 * 说明:JAVA中大多数对象都会存储在堆(Heap)中,但对于一些没有逃逸的小对象
 * 现在也可能分配在栈上(JVM发展历程中的一种新的优化方式。)。
 */
public class TestGC03 {
    //-XX:+PrintGCDetails
	public static void main(String[] args) {
		for(int i=0;i<100000000;i++) {
			doMethod01();
		}
	}
	
	static byte[] b2;
	static void doMethod01() {
	   //小对象,未逃逸,栈上分配,栈上分配对象的对象,方法调用结束,对象销毁。
	   //byte[] b1=new byte[1024*1024]; //小对象,未逃逸(方法外界没有引用指向此对象),可以直接分配在栈上
	   //小对象,已逃逸,堆上分配,对象回收需要借助GC系统。
	   b2=new byte[1];//小对象,但逃逸了(方法外部有引用指向此对象),对象分配在堆上
	}
	//JDK8中默认会打开逃逸分析选项,希望未逃逸的小对象分配在栈上,这样可以避免启动GC对对象进行回收。
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JackHuan_code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值