GC,Reference,Finalize,Dispose
Java提供了垃圾对象自动回收(GC)机制,该机制对堆heap里的对象就其被引用情况进行跟踪判断,对合适对象进行自动回收释放内存。按java规范,对象分如下引用情况:
An object is strongly reachable if it can be reached by some thread without traversing any reference objects. A newly-created object is strongly reachable by the thread that created it.
An object is softly reachable if it is not strongly reachable but can be reached by traversing a soft reference.
An object is weakly reachable if it is neither strongly nor softly reachable but can be reached by traversing a weak reference. When the weak references to a weakly-reachable object are cleared, the object becomes eligible for finalization.
An object is phantom reachable if it is neither strongly, softly, nor weakly reachable, it has been finalized, and some phantom reference refers to it.
Finally, an object is unreachable, and therefore eligible for reclamation, when it is not reachable in any of the above ways.
根据引用情况不同,GC处理过程也不同。
当一个对象实例不被强引用strongly reachable时,GC的某次运行就有可能扫描到该对象。这时GC会检查该对象是否softreference reachable,如果是,则尽可能放它一马,一笑而过,但如果放过去就会引起out of memory error,则就要处理该对象。处理过程首先要检查是否实现了finalize方法的对象,如果是则标记finalizable,并导致Finalizer系统线程(setDaemon(true),Thread.MAX_PRIORITY - 2)在后续巡检中对此对象调用finalize方法。执行完finalize方法后如果在此后某次的GC运行中再次被发现softreference reachable,则此时导致clear softreference,并释放内存,最后归到softreference-queue中。
如果本对象没有实现finalize方法,则GC省去其对应处理环节。
此过程同样适用于weakreference reachable,所不同的是GC将不会尽可能放过该对象。
对于PhantomReference reachable,情况不同之处在于PhantomReference reachable定义在finalize已经执行结束后的GC的某次运行时,这个时候,它不去PhantomReference clear,也不释放内存,而是直接归到PhantomReference-queue中,此后需要应用程序自行clear才能释放,这也是PhantomReference一定要求queue的原因。
基于此GC机制,对“实现当不使用某对象时释放其附属资源”这样的需求,java提供两种实现方式。
Finalize方式就是指Object class的那个Finalize方法,可以被任何class进行override来实现释放对应附属资源。由于历史原因,执行该finalize方法的Finalizer线程保留为一个低优先级线程,因此导致获得巡检机会从而进行资源释放将不是十分及时;另外,java规范允许在finalize方法中再次使该对象恢复强引用,因而GC总是在执行finalize后的再次运行中才考虑释放该对象的内存,如果该对象本身占用内存比较大,这样同样导致整体资源释放将不是十分及时。最后,如果一个class实现了finalize方法,不仅如上所述释放其实例时比较占用机器资源,建立实例的过程也将因要通过必须的finalize方法检测及底层register而占用额外的资源。为此,java提供了Dispose模式可以用来替代finalize模式。
Dispose方式的实现就不在class里实现finalize方法了。在jre中,已经为java2D的支持实现了一个Disposer用来帮助释放对象附用的图形资源,下面以此为例说明Dispose方式。
sun.java2d.Dispose随着类加载初始化构建一个Java2D Disposer线程(setDaemon(true),Thread.MAX_PRIORITY),同时该类对外提供public static addRecord(Object target, DisposerRecord rec)用来建立对指定target的weakreference或 PhantomReference(系统属性sun.java2d.reftype指定)监测。当指定对象target失去强引用而成为weakreference或PhantomReference reachable时,会被GC及时置入reference-queue中,同时被高优先级的本Java2D Disposer线程及时监测到,然后本线程会去从reference-queue中拿到此reference,并通过内部映射表hashtable找到当初addRecord时传入的DisposerRecord,并调用其dispose()。所以在该dispose方法中实现释放附属资源的逻辑就可以了。
分享到:
相关推荐
- 如果实现了`Finalize`方法,则应该在`Dispose`方法中调用`GC.SuppressFinalize(this)`来抑制`Finalize`方法的执行,以避免重复释放资源。 - `Dispose`方法应该能够释放所有非托管资源。 - 当`Dispose`方法完成...
不同于`Dispose()`,`Finalize()`是不可控的,因为GC何时运行析构函数是不确定的。这可能导致资源释放延迟,甚至在某些情况下,如果对象被重新引用,析构函数可能不会被调用。因此,设计良好的代码应依赖于`Dispose...
所有对象被 Garbage Collection 时自动调用,例如运行 System.gc() 时;2. 程序退出时为每个对象调用一次 finalize 方法;3. 显式的调用 finalize 方法。 需要注意的是,finalize() 方法的调用是不确定的,JVM 不...
C#的垃圾回收机制(Garbage Collector, GC)虽然能够自动管理托管资源(如内存),但对非托管资源的清理则需要程序员手动干预,这就是`Dispose`模式的用武之地。 `Dispose`方法通常在实现了`IDisposable`接口的类中...
当一个对象不再被引用且即将被垃圾回收器(GC)回收时,如果该对象实现了 `finalize` 方法,那么在 GC 执行前,会调用该对象的 `finalize` 方法。然而,`finalize` 的使用并不推荐,原因有以下几点: 1. **不可靠...
在本课程"【IT十八掌徐培成】Java基础第26天-03.JVM结构-finalize-gc"中,我们将深入探讨JVM的结构、`finalize`方法以及垃圾收集(Garbage Collection,简称GC)机制。以下是这些主题的详细阐述: 1. JVM结构: - ...
在Java编程语言中,垃圾回收(Garbage Collection, GC)是一项自动管理内存的重要机制,它负责识别并清除不再使用的对象,以防止内存泄漏。垃圾回收是Java与C++等其他语言的一大区别,它使得程序员无需手动管理内存...
Java 中 finalize 方法使用 finalize 方法是 Java 编程语言中一个非常重要的方法,它与 Java 编程中的垃圾回收器有着紧密的关系。当一个对象变成一个垃圾对象的时候,如果此对象的内存被回收,那么就可以调用系统中...
Java 技术允许使用finalize() 方法在垃圾收集器将对象从内存中清除出去 之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对 象调用的。它是在Object 类中定义的,因此所有的类都...
1. **性能影响**:为了支持`finalize()`方法,GC需要对覆盖了该方法的对象进行额外跟踪。 2. **可达性问题**:`finalize()`方法执行后,对象可能再次变为可达状态,从而导致GC需要重新评估其可达性。 3. **非确定性...
//为false时肯定是GC调用了对象的Finalize方法,所以没有必要再告诉GC你不要调用我的Finalize方法啦 if (disposing) { GC.SuppressFinalize(this); } } } static void Main(string[] args) { //tmpObj1...
Java虚拟机(JVM)中的垃圾收集(Garbage Collection,简称GC)是自动管理内存的重要机制,它负责识别并回收不再使用的对象所占用的内存,从而确保程序的内存效率。理解GC的基本原理对于优化Java应用的性能至关重要...
同时,`Dispose`方法可以用来阻止垃圾回收器调用Finalize,通过`GC.SuppressFinalize(this)`实现。 此外,C#提供了一种叫做`using`语句的结构,它确保在代码块结束时(即遇到右花括号时)会自动调用`Dispose`方法,...
"前端项目-css3finalize.zip" 这个标题表明这是一个关于前端开发的项目,主要聚焦在CSS3的应用。"css3finalize"可能指的是一个工具或库,用于帮助开发者完成CSS3代码,尤其是自动添加浏览器厂商前缀,以确保在不同...
C#程序员需要理解.NET Framework的垃圾收集机制,以便正确地使用Finalize和Dispose方法。 错误7:没有正确地使用基类的Finalize方法 在C#中,需要显示地调用基类的Finalize方法,以便正确地释放非托管资源。 错误...
在Java编程语言中,`final`, `finally`, 和 `finalize` 是三个非常重要的关键字,它们各自扮演着不同的角色,尤其在处理程序的可预测性、数据的不可变性和垃圾回收等方面。下面将详细阐述这三个关键字的区别及其应用...
为了防止资源的双重释放,当实现了`Dispose`方法时,应在`Finalize`中调用`GC.SuppressFinalize`来指示GC不再调用该对象的`Finalize`方法。此外,C#还引入了`using`语句,它是一种结构化的异常安全资源管理方式,...
此外,还应调用`GC.SuppressFinalize`来告诉垃圾回收器不再需要调用`Finalize`方法,以避免重复释放资源。 **示例代码**: ```csharp public class MyResource : IDisposable { public void Dispose() { // 执行...
Java垃圾回收(GC)是Java编程中至关重要的一个部分,对于任何希望成为优秀Java程序员的人来说,理解其工作原理是必不可少的。GC的主要任务是自动管理内存,尤其是对象的分配和回收,以避免内存泄漏和资源浪费。在...