学习笔记之JavaSE(14)--面向对象编程5

开始今天的学习之前,先做个小总结

从10.24到现在,我已经学习了Java技术架构的划分、Java工作原理、Java环境配置、Java主类结构、关键字与标识符、变量与常量、运算符、流程控制、方法和方法重载、数组和Arrays类、哈希值与内存地址、==运算符与equals()、JVM工作原理、面向对象编程思想、类与对象关系、封装、权限修饰符、构造函数、this关键字、static关键字和变量的初始化方式。学习到很多新的细节知识,尤其是通过JVM工作原理把之前很多死记硬背的知识点彻底理解了~


今天的学习内容是垃圾回收机制


通过之前的学习,我们已经知道对象是如何创建并初始化的, 那么如何清理对象呢?换句话说,我们已经知道静态变量随着JVM进程结束而销毁,局部变量随着方法调用结束而销毁,实例变量随着对象的清理而销毁,那么如何清理对象呢?这就要说到Java的垃圾回收机制

一旦对象失去了“遥控器”,它就成了“可回收”的对象,垃圾回收器(GC)就会将这些对象识别为“垃圾”,当内存不足时就会自动回收这些“垃圾”以清理内存。但GC只能回收那些用new操作符创建的对象,如果某些对象不是通过new操作符在内存获取一块内存区域,这种对象可能不被GC所识别(比如Native方法调用的malloc()或者在创建对象时打开的某些文件资源)。为了应对这种情况,Java允许在类中覆盖Object类的finalize()的方法,先将这部分内存区域清理掉。该方法的工作原理为:一旦GC准备好释放某对象占用的内存空间,将首先调用其finalize()方法执行一些必要的清理工作,并且在下一次垃圾回收动作发生时,才会真正回收该对象占用的内存。

注意:如果JVM并未面临内存耗尽的情况,是不会浪费CPU资源去执行GC或finalize()方法的(垃圾回收线程。为此,Java提供了System.gc()方法和Runtime.gc()方法,但这两个方法的作用只是提醒虚拟机:程序员希望进行一次垃圾回收。但是它不能保证垃圾回收一定会进行,而且具体什么时候进行是取决于具体的虚拟机的,不同的虚拟机有不同的对策。结论:程序员无法强制启动GC!!

示例程序:

public class Test28 {

	public static void main(String[] args){
		Test28 t1=new Test28();//t1引用了别的对象,这个对象变为可回收的
		t1=new Test28();
		
		Test28 t2=new Test28();//t2被赋值为null,这个对象变为可回收的
		t2=null;
		
		go();
		
		System.gc();//强制启动GC
	}
	
	public static void go(){
		Test28 t3=new Test28();//go()方法调用结束,t3会被销毁,这个对象变为可回收的
	}
	
	//Object类的方法,用来回收不是通过new分配内存的对象
	 protected void finalize(){
		 System.out.println("调用finalize()");
	 }
}

我们可以看到,程序中描述了对象变为“可回收”的三种情况,并且在最后调用了System.gc()强制启动GC。程序运行结果是finalize()方法被调用了三次,也就是说每个对象的回收都会先调用其finalize()方法,然后再使用GC回收该对象占用的内存


面试题:常见的GC垃圾收集算法?

答:标记-清除算法、复制算法、标记-整理算法,分代收集算法

其中分代收集算法是最常用的算法,一般是把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记—清理”或者“标记—整理”算法来进行回收。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值