Chinaunix首页 | 论坛 | 博客
  • 博客访问: 16493185
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 21:46:46

下载本文示例代码
  最终化允许实现Java对象的最后清理;但是,就算不显式地使用它,它也能延迟资源的回收。在本文中你还会学习如何避免类似的内存保留问题。  一、 引言  最终化是Java编程语言的一个特性:它允许你对垃圾收集器发现的不可达的对象进行最后清理。典型地用于回收与一对象相关联的本地资源。下面是一个简单的最终化示例: public class Image1 { //指向本地图像数据 private int nativeImg; private Point pos; private Dimension dim; //它释放本地图像; //随后对它的调用将被忽略 private native void disposeNative(); public void dispose() { disposeNative(); } protected void finalize() { dispose(); } static private Image1 randomImg;} 图1.一个可最终化的对象  有时,在一个Image1实例变为不可达的时,Java虚拟机(JVM)将调用它的finalize()方法来确保含有图像数据(在本例中被整数nativeImg所指向)的本地资源已经被回收。然而,请注意,该finalize()方法,先不管它被JVM进行专门对待,是一个任意的方法-它包含任意的代码。特别地,它能存取任何对象中的任何字段(在本例中指pos和dim)。令人惊讶的是,它还能使该对象再次成为可达的-比如说通过让它从一个静态字段成为可达的(如,randomImg=this;)。我根本不推荐使用后面这种编程实践,但是遗憾的是,Java编程语言允许它。  下面步骤描述一个可最终化的对象obj的生命周期-也即,这是一个其类中有一个非平凡的(non-trivial)终结器的对象(见图1): 图2.垃圾收集器确定这个obj是不可达的  1. 当obj被分配时,JVM内部地记录下这个obj是可最终化的(这在典型情况下会减慢现代JVM具有的其它方面的分配路径)。  2. 当垃圾收集器确定该obj是不可达的时,它注意到,这个obj是可最终化的(因为它在分配时就被记录下来)并且把它添加到JVM的最终化队列上。它还确保从obj可达的所有对象被保留起来,即使它们从其它对象也许是不可达的,因为它们可能会被终结器所存取。图2展示了Image1的一个实例的情况。  3. 在后面的时候,JVM的终结器线程将出队obj,调用它的finalize()方法,并且记录下该obj的终结器已经被调用。此时,obj被认为是被最终化的。  4. 当垃圾收集器再次发现该obj是不可达的时,它将连同一切它所可达的(假定后者是不可达的)对象回收它的空间。  注意,垃圾收集器至少需要两个周期(也许更多)来回收obj并且需要保留在该过程中所有另外的从obj可达的对象。如果一个程序员不小心,那么这可能会创建暂时的、微妙的和无法预言的资源保留问题。另外,JVM并不保证它将调用所有的已分配的可最终化的对象的终结器;它可能在垃圾收集器发现它们其中一些是不可达的之前就已退出。共4页。 1 2 3 4 :   最终化允许实现Java对象的最后清理;但是,就算不显式地使用它,它也能延迟资源的回收。在本文中你还会学习如何避免类似的内存保留问题。  一、 引言  最终化是Java编程语言的一个特性:它允许你对垃圾收集器发现的不可达的对象进行最后清理。典型地用于回收与一对象相关联的本地资源。下面是一个简单的最终化示例: public class Image1 { //指向本地图像数据 private int nativeImg; private Point pos; private Dimension dim; //它释放本地图像; //随后对它的调用将被忽略 private native void disposeNative(); public void dispose() { disposeNative(); } protected void finalize() { dispose(); } static private Image1 randomImg;} 图1.一个可最终化的对象  有时,在一个Image1实例变为不可达的时,Java虚拟机(JVM)将调用它的finalize()方法来确保含有图像数据(在本例中被整数nativeImg所指向)的本地资源已经被回收。然而,请注意,该finalize()方法,先不管它被JVM进行专门对待,是一个任意的方法-它包含任意的代码。特别地,它能存取任何对象中的任何字段(在本例中指pos和dim)。令人惊讶的是,它还能使该对象再次成为可达的-比如说通过让它从一个静态字段成为可达的(如,randomImg=this;)。我根本不推荐使用后面这种编程实践,但是遗憾的是,Java编程语言允许它。  下面步骤描述一个可最终化的对象obj的生命周期-也即,这是一个其类中有一个非平凡的(non-trivial)终结器的对象(见图1): 图2.垃圾收集器确定这个obj是不可达的  1. 当obj被分配时,JVM内部地记录下这个obj是可最终化的(这在典型情况下会减慢现代JVM具有的其它方面的分配路径)。  2. 当垃圾收集器确定该obj是不可达的时,它注意到,这个obj是可最终化的(因为它在分配时就被记录下来)并且把它添加到JVM的最终化队列上。它还确保从obj可达的所有对象被保留起来,即使它们从其它对象也许是不可达的,因为它们可能会被终结器所存取。图2展示了Image1的一个实例的情况。  3. 在后面的时候,JVM的终结器线程将出队obj,调用它的finalize()方法,并且记录下该obj的终结器已经被调用。此时,obj被认为是被最终化的。  4. 当垃圾收集器再次发现该obj是不可达的时,它将连同一切它所可达的(假定后者是不可达的)对象回收它的空间。  注意,垃圾收集器至少需要两个周期(也许更多)来回收obj并且需要保留在该过程中所有另外的从obj可达的对象。如果一个程序员不小心,那么这可能会创建暂时的、微妙的和无法预言的资源保留问题。另外,JVM并不保证它将调用所有的已分配的可最终化的对象的终结器;它可能在垃圾收集器发现它们其中一些是不可达的之前就已退出。共4页。 1 2 3 4 : 下载本文示例代码


怎样处理Java最终化的内存保留问题怎样处理Java最终化的内存保留问题怎样处理Java最终化的内存保留问题怎样处理Java最终化的内存保留问题怎样处理Java最终化的内存保留问题怎样处理Java最终化的内存保留问题怎样处理Java最终化的内存保留问题怎样处理Java最终化的内存保留问题怎样处理Java最终化的内存保留问题怎样处理Java最终化的内存保留问题怎样处理Java最终化的内存保留问题怎样处理Java最终化的内存保留问题怎样处理Java最终化的内存保留问题怎样处理Java最终化的内存保留问题怎样处理Java最终化的内存保留问题
阅读(141) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~