system.gc会立即执行垃圾回收吗_[基础篇]-面向对象-07-垃圾回收

垃圾回收

1.对象和垃圾回收

Java的垃圾回收的java语言重要的功能之一,当程序创建对象,数组,或者引用对象,系统都会在内存中为其分配一个空间,对象就是保存在这个内存区域中,当这块内存区域不再被任何变量引用,这个内存就变为垃圾,等待垃圾回收机制进行回收。

垃圾回收具有以下特点:

  • 垃圾回收机制只负责回收堆内存中的对象,不会回收任何物理资源(比如数据库连接,网络,IO等)
  • 程序无法精确的控制垃圾回收的运行,垃圾回收会在合适的时候进行,当对象永久性的失去引用,系统会在合适的时候回收它所占的内存。
  • 在垃圾回收机制回收任何对象之前,都会调用它的finalize方法,该方法可能使该对象重新复活,从而导致垃圾回收机制的取消。

1.1对象在内存中的状态

当一个对象在堆内存中运行的时候,根据它引用的状态,可以把它所处的状态分为三种情况:

  • 可达状态:当创建一个对象后,如果有一个以上的引用变量引用它,则这个对象处于可达状态,程序可以通过对象的实例变量和方法进行调用。
  • 可恢复状态:如果程序中的某个对象不再有任何引用变量引用它,它就进入到了可恢复状态,在这个状态下,系统的垃圾回收机制准备回收这该对象所占的内存。,在回收该对象之前会调用该对象的finalize方法,看是否还有其他变量引用,如果有可以由可恢复状态进入到可达状态。
  • 不可达状态: 当对象与所有引用变量的关联都被切断,并且系统已经调用该对象的finalize方法也无法进入到可达状态, 从而导致进入不可达状态, 系统才会进行垃圾回收。

案例分析:

public class StatusTest {
	public void test() {
		/**
		 * 当执行下方代码:定义一个变量a,并且执行内存的"Spring入门基础"字符串     
		 * 此时"Spring入门基础"处于可达状态
		 */
		String a=new String("Spring入门基础");
		/**
		 * 创建了一个新的对象 "redis基础"字符串对象     
		 * 让a变量引用这个 "redis基础"字符串对象,此时"Spring入门基础"这个字符串
		 * 对象没有任何变量引用 ,进入到可恢复状态。分析可知此时 "redis基础" 是可达状态
		 */
		a=new String("redis基础");
	}
}

1ae0bdc744e28f12ec7536c5558bef26.png

1.2强制垃圾回收

当一个对象失去引用后,系统何时调用它的finalize方法执行资源清理,何时会进入到不可达状态,

对于程序来说,程序员无法精准的控制系统何时进行垃圾回收,也无法明确在什么时间进行垃圾回收,程序只能控制一个对象不再被任何变量引用,绝不能控制它在何时被垃圾回收。

虽然程序无法精准的控制垃圾回收,但是依然可以通过代码指定系统进行强制垃圾回收。但是系统执行垃圾回收仍然是不确定的,大部分时候程序员只能指定强制垃圾回收,但是在何时进行还是由jvm自身决定。

系统有如下方式可以进行强制垃圾回收:

  • 调用System类的gc方法
  • 调用Runtime类的gc方法
public class GcTest {
	public static void main(String[] args) {
		for (int i = 0; i < 5; i++) {
			GcTest gc = new GcTest();
			/**执行强制垃圾回收.. 一旦执行垃圾回收 系统会调用这个对象finalize方法看
			 * 是否可以进入到可达状态虽然指定了强制垃圾回收 ,但是系统会自己觉得什么时候
			 * 执行垃圾回收.. -->System.gc();
			 */
			Runtime.getRuntime().gc();
			//java  -verbose:gc GcTest 这个命令详细查看垃圾回收的执行
		}
	}
	/**
	 * 分析:按理来说强制执行应该是循环执行五次,但从结果显示可知System.gc();并不是立即执行
	 * finalize方法,而是通知系统进行垃圾回收,但具体什么时候执行还是要由系统自行决定
	 * 调用了System.gc()进行垃圾回收,但由系统自行决定执行的时间或者是执不执行,因此每次运行
	 * 结果输出的次数都会小于5(调用的次数)
	 */
	@Override
	protected void finalize() throws Throwable {
		System.out.println("系统正在执行清理GcTest这个对象....");
	}
}

1.3 Finalize方法

在垃圾回收机制回收某个对象所占用的内存,会调用这个对象的finalize方法。

Finalize方法有4个特点:

  • 不要主动调用某个对象的finalize方法,把该方法交给垃圾回收机制自动执行
  • Finalize方法何时被调用,是否被调用 都是不确定的,不要把finalize方法当做一定会执行的方法。
  • 在jvm执行可恢复对象的finalize方法 可以使该对象或者系统中的其他对象重新进行到可达状态
  • 当jvm执行finalize 如果出现异常, 垃圾回收并不会报告异常,程序可以继续执行。
public class FinalizeTest {
	private static  FinalizeTest ft=null;
	public  void info()
	{
		System.out.println("系统正在执行垃圾回收....");
	}
	public static void main(String[] args) 
	{
		//1.创建FinalizeTest对象,没有任何变量引用 ,进入到可恢复状态
		new FinalizeTest();
		//2.通知系统进行强制垃圾回收,但不一定会立即执行finalize方法
		System.gc();
		//3.强制垃圾回收机制 调用可恢复对象的finalize方法,此时ft便初始化完成
		System.runFinalization();
		//4.ft初始化完成,便可执行info方法
		ft.info();
	}
	public void finalize()  {
		ft=this;
	}
}

2.自我提升

自我学习,了解垃圾回收的算法。至少掌握三种以上。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值