finalize()和system.gc()的区别

finalize()是由JVM自动调用的,你可以用System.gc(),但JVM不一定会立刻执行,JVM感觉内存空间有限时,才会开始执行finalize(),至于新的对象创建个数和被收集个数不同是因为收集的对象只和JVM的垃圾收集策略有关。

(1) finalize()函数是干嘛的?Java不是有Garbage Collection(以下简称gc)来负责回收内存吗?
gc只能清除在堆上分配的内存(纯java语言的所有对象都在堆上使用new分配内存),而不能清除栈上分配的内存(当使用JNI技术时,可能会在栈上分配内存,例如java调用c程序,而该c程序使用malloc分配内存时)。因此,如果某些对象被分配了栈上的内存区域,那gc就管不着了,对这样的对象进行内存回收就要靠finalize()。
举个例子来说,当java调用非java方法时(这种方法可能是c或是c++的),在非java代码内部也许调用了c的malloc()函数来分配内存,而且除非调用那个了free()否则不会释放内存(因为free()是c的函数),这个时候要进行释放内存的工作,gc是不起作用的,因而需要在finalize()内部的一个固有方法调用它(free())。
finalize的工作原理应该是这样的:一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象的内存。所以如果使用finalize(),就可以在垃圾收集期间进行一些重要的清除或清扫工作。

(2) finalize()在什么时候被调用?
有三种情况
1.所有对象被Garbage Collection时自动调用,比如运行System.gc()的时候;
2.程序退出时为每个对象调用一次finalize方法;
3.显式的调用finalize方法
除此以外,正常情况下,当某个对象被系统收集为无用信息的时候,finalize()将被自动调用,但是jvm不保证finalize()一定被调用,也就是说,finalize()的调用是不确定的,这也就是为什么sun不提倡使用finalize()的原因。

转自:http://sunanjie1986.blog.163.com/blog/static/2092869120096134349658/

//: initialization/E10_FinalizeCall.java
/****************** Exercise 10 *****************
 * Create a class with a finalize() method that
 * prints a message. In main(), create an object
 * of your class. Explain the behavior of your
 * program.
 ************************************************/
package initialization;

public class E10_FinalizeCall {
	protected void finalize() {
		System.out.println("finalize() called");
	}

	public static void main(String args[]) {
		new E10_FinalizeCall();
	}
} ///:~

 
You probably won’t see the finalizer called because the program doesn’t usually generate enough garbage for the collector to run. 

//: initialization/E11_FinalizeAlwaysCalled.java
/****************** Exercise 11 ****************
 * Modify Exercise 10 so your
 * finalize() will always be called.
 ***********************************************/
package initialization;

public class E11_FinalizeAlwaysCalled {
	protected void finalize() {
		System.out.println("finalize() called");
	}

	public static void main(String args[]) {
		new E11_FinalizeAlwaysCalled();
		System.gc();
		System.runFinalization();
	}
} /*
* Output: finalize() called
*///:~
Calling System.gc( ) and System.runFinalization( ) in sequence will probably but not necessarily call your finalizer (The behavior of finalize has been uncertain from one version of JDK to another.) The call to these methods is just a request; it doesn’t ensure the finalizer will actually run. Ultimately, nothing guarantees that finalize( ) will be called.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值