- 浏览: 536317 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
飞天奔月:
public List<String> gener ...
实践中的重构30_不做油漆匠 -
在世界的中心呼喚愛:
在世界的中心呼喚愛 写道public class A {
...
深入理解ReferenceQueue GC finalize Reference -
在世界的中心呼喚愛:
在世界的中心呼喚愛 写道在世界的中心呼喚愛 写道在classB ...
深入理解ReferenceQueue GC finalize Reference -
在世界的中心呼喚愛:
在世界的中心呼喚愛 写道在classB的finalize上打断 ...
深入理解ReferenceQueue GC finalize Reference -
在世界的中心呼喚愛:
iteye比较少上,如果可以的话,可以发e-mail交流:ch ...
深入理解ReferenceQueue GC finalize Reference
目录
基本预备相关知识
对象的销毁过程
对象重生的例子
对象的finalize的执行顺序
何时及如何使用finalize
参考
基本预备相关知识
1 java的GC只负责内存相关的清理,所有其它资源的清理必须由程序员手工完成。要不然会引起资源泄露,有可能导致程序崩溃。
2 调用GC并不保证GC实际执行。
3 finalize抛出的未捕获异常只会导致该对象的finalize执行退出。
4 用户可以自己调用对象的finalize方法,但是这种调用是正常的方法调用,和对象的销毁过程无关。
5 JVM保证在一个对象所占用的内存被回收之前,如果它实现了finalize方法,则该方法一定会被调用。Object的默认finalize什么都不做,为了效率,GC可以认为一个什么都不做的finalize不存在。
6 对象的finalize调用链和clone调用链一样,必须手工构造。
如
对象的销毁过程
在对象的销毁过程中,按照对象的finalize的执行情况,可以分为以下几种,系统会记录对象的对应状态:
unfinalized 没有执行finalize,系统也不准备执行。
finalizable 可以执行finalize了,系统会在随后的某个时间执行finalize。
finalized 该对象的finalize已经被执行了。
GC怎么来保持对finalizable的对象的追踪呢。GC有一个Queue,叫做F-Queue,所有对象在变为finalizable的时候会加入到该Queue,然后等待GC执行它的finalize方法。
这时我们引入了对对象的另外一种记录分类,系统可以检查到一个对象属于哪一种。
reachable 从活动的对象引用链可以到达的对象。包括所有线程当前栈的局部变量,所有的静态变量等等。
finalizer-reachable 除了reachable外,从F-Queue可以通过引用到达的对象。
unreachable 其它的对象。
来看看对象的状态转换图。
好大,好晕,慢慢看。
1 首先,所有的对象都是从Reachable+Unfinalized走向死亡之路的。
2 当从当前活动集到对象不可达时,对象可以从Reachable状态变到F-Reachable或者Unreachable状态。
3 当对象为非Reachable+Unfinalized时,GC会把它移入F-Queue,状态变为F-Reachable+Finalizable。
4 好了,关键的来了,任何时候,GC都可以从F-Queue中拿到一个Finalizable的对象,标记它为Finalized,然后执行它的finalize方法,由于该对象在这个线程中又可达了,于是该对象变成Reachable了(并且Finalized)。而finalize方法执行时,又有可能把其它的F-Reachable的对象变为一个Reachable的,这个叫做对象再生。
5 当一个对象在Unreachable+Unfinalized时,如果该对象使用的是默认的Object的finalize,或者虽然重写了,但是新的实现什么也不干。为了性能,GC可以把该对象之间变到Reclaimed状态直接销毁,而不用加入到F-Queue等待GC做进一步处理。
6 从状态图看出,不管怎么折腾,任意一个对象的finalize只至多执行一次,一旦对象变为Finalized,就怎么也不会在回到F-Queue去了。当然没有机会再执行finalize了。
7 当对象处于Unreachable+Finalized时,该对象离真正的死亡不远了。GC可以安全的回收该对象的内存了。进入Reclaimed。
对象重生的例子
期待输出
但是有可能失败,源于GC的不确定性以及时序问题,多跑几次应该可以有成功的。详细解释见文末的参考文档。
对象的finalize的执行顺序
所有finalizable的对象的finalize的执行是不确定的,既不确定由哪个线程执行,也不确定执行的顺序。
考虑以下情况就明白为什么了,实例a,b,c是一组相互循环引用的finalizable对象。
何时及如何使用finalize
从以上的分析得出,以下结论。
1 最重要的,尽量不要用finalize,太复杂了,还是让系统照管比较好。可以定义其它的方法来释放非内存资源。
2 如果用,尽量简单。
3 如果用,避免对象再生,这个是自己给自己找麻烦。
4 可以用来保护非内存资源被释放。即使我们定义了其它的方法来释放非内存资源,但是其它人未必会调用该方法来释放。在finalize里面可以检查一下,如果没有释放就释放好了,晚释放总比不释放好。
5 即使对象的finalize已经运行了,不能保证该对象被销毁。要实现一些保证对象彻底被销毁时的动作,只能依赖于java.lang.ref里面的类和GC交互了。
参考
关于引用类型,GC,finalize的相互交互可以参考ReferenceQueue GC finalize Reference 测试及相关问题
菜鸟同问
囧,没注意到
@Override
public void finalize() {
System.out.println("A finalize");
C.a = this;
}
有个C.a = this;
菜鸟同问
考虑如下场景:
A有一个B的引用。然后A变成垃圾,有待回收。在GC的作用下,A和B被加入F-QUEUE。
这种场景下,B在其他地方应该没有强引用吧?
恩。
A和B都是F-Reachable+Finalizable。
当回收A时,A从F-Reachable+Finalizable变到Reachable+Finalized。但是B此时还是在F-QUEUE的,B的状态变成Reachable+Finalizable(因为A的状态为Reachable)。
这样的话,A是经历了F-Reachable+Finalizable,得以从Reachable+Finalizable发展到Reachable+Finalized的吧,那最后那个B
以后GC回收B的时候B的状态就从Reachable+Finalizable变为Reachable+Finalized。
是不是也要经历F-Reachable+Finalizable这个状态,直接从这两个状态切换可以吗?
麻烦楼主了!感激不尽
B刚开始是在F-Reachable+Finalizable,然后因为A的关系跳到Reachable+Finalizable,GC对其回收的时候跳到Reachable+Finalized。
考虑如下场景:
A有一个B的引用。然后A变成垃圾,有待回收。在GC的作用下,A和B被加入F-QUEUE。
这种场景下,B在其他地方应该没有强引用吧?
A和B都是F-Reachable+Finalizable。
当回收A时,A从F-Reachable+Finalizable变到Reachable+Finalized。但是B此时还是在F-QUEUE的,B的状态变成Reachable+Finalizable(因为A的状态为Reachable)。
这样的话,A是经历了F-Reachable+Finalizable,得以从Reachable+Finalizable发展到Reachable+Finalized的吧,那最后那个B
以后GC回收B的时候B的状态就从Reachable+Finalizable变为Reachable+Finalized。
是不是也要经历F-Reachable+Finalizable这个状态,直接从这两个状态切换可以吗?
麻烦楼主了!感激不尽
考虑如下场景:
A有一个B的引用。然后A变成垃圾,有待回收。在GC的作用下,A和B被加入F-QUEUE。
A和B都是F-Reachable+Finalizable。
当回收A时,A从F-Reachable+Finalizable变到Reachable+Finalized。但是B此时还是在F-QUEUE的,B的状态变成Reachable+Finalizable(因为A的状态为Reachable)。
以后GC回收B的时候B的状态就从Reachable+Finalizable变为Reachable+Finalized。
对
下一个不是F queue啊。下一个是F-Reachable+Finalized.
进入F-Queue的状态是F-Reachable+Finalizable。
基本预备相关知识
对象的销毁过程
对象重生的例子
对象的finalize的执行顺序
何时及如何使用finalize
参考
基本预备相关知识
1 java的GC只负责内存相关的清理,所有其它资源的清理必须由程序员手工完成。要不然会引起资源泄露,有可能导致程序崩溃。
2 调用GC并不保证GC实际执行。
3 finalize抛出的未捕获异常只会导致该对象的finalize执行退出。
4 用户可以自己调用对象的finalize方法,但是这种调用是正常的方法调用,和对象的销毁过程无关。
5 JVM保证在一个对象所占用的内存被回收之前,如果它实现了finalize方法,则该方法一定会被调用。Object的默认finalize什么都不做,为了效率,GC可以认为一个什么都不做的finalize不存在。
6 对象的finalize调用链和clone调用链一样,必须手工构造。
如
protected void finalize() throws Throwable { super.finalize(); }
对象的销毁过程
在对象的销毁过程中,按照对象的finalize的执行情况,可以分为以下几种,系统会记录对象的对应状态:
unfinalized 没有执行finalize,系统也不准备执行。
finalizable 可以执行finalize了,系统会在随后的某个时间执行finalize。
finalized 该对象的finalize已经被执行了。
GC怎么来保持对finalizable的对象的追踪呢。GC有一个Queue,叫做F-Queue,所有对象在变为finalizable的时候会加入到该Queue,然后等待GC执行它的finalize方法。
这时我们引入了对对象的另外一种记录分类,系统可以检查到一个对象属于哪一种。
reachable 从活动的对象引用链可以到达的对象。包括所有线程当前栈的局部变量,所有的静态变量等等。
finalizer-reachable 除了reachable外,从F-Queue可以通过引用到达的对象。
unreachable 其它的对象。
来看看对象的状态转换图。
好大,好晕,慢慢看。
1 首先,所有的对象都是从Reachable+Unfinalized走向死亡之路的。
2 当从当前活动集到对象不可达时,对象可以从Reachable状态变到F-Reachable或者Unreachable状态。
3 当对象为非Reachable+Unfinalized时,GC会把它移入F-Queue,状态变为F-Reachable+Finalizable。
4 好了,关键的来了,任何时候,GC都可以从F-Queue中拿到一个Finalizable的对象,标记它为Finalized,然后执行它的finalize方法,由于该对象在这个线程中又可达了,于是该对象变成Reachable了(并且Finalized)。而finalize方法执行时,又有可能把其它的F-Reachable的对象变为一个Reachable的,这个叫做对象再生。
5 当一个对象在Unreachable+Unfinalized时,如果该对象使用的是默认的Object的finalize,或者虽然重写了,但是新的实现什么也不干。为了性能,GC可以把该对象之间变到Reclaimed状态直接销毁,而不用加入到F-Queue等待GC做进一步处理。
6 从状态图看出,不管怎么折腾,任意一个对象的finalize只至多执行一次,一旦对象变为Finalized,就怎么也不会在回到F-Queue去了。当然没有机会再执行finalize了。
7 当对象处于Unreachable+Finalized时,该对象离真正的死亡不远了。GC可以安全的回收该对象的内存了。进入Reclaimed。
对象重生的例子
class C { static A a; } class A { B b; public A(B b) { this.b = b; } @Override public void finalize() { System.out.println("A finalize"); C.a = this; } } class B { String name; int age; public B(String name, int age) { this.name = name; this.age = age; } @Override public void finalize() { System.out.println("B finalize"); } @Override public String toString() { return name + " is " + age; } } public class Main { public static void main(String[] args) throws Exception { A a = new A(new B("allen", 20)); a = null; System.gc(); Thread.sleep(5000); System.out.println(C.a.b); } }
期待输出
A finalize B finalize allen is 20
但是有可能失败,源于GC的不确定性以及时序问题,多跑几次应该可以有成功的。详细解释见文末的参考文档。
对象的finalize的执行顺序
所有finalizable的对象的finalize的执行是不确定的,既不确定由哪个线程执行,也不确定执行的顺序。
考虑以下情况就明白为什么了,实例a,b,c是一组相互循环引用的finalizable对象。
何时及如何使用finalize
从以上的分析得出,以下结论。
1 最重要的,尽量不要用finalize,太复杂了,还是让系统照管比较好。可以定义其它的方法来释放非内存资源。
2 如果用,尽量简单。
3 如果用,避免对象再生,这个是自己给自己找麻烦。
4 可以用来保护非内存资源被释放。即使我们定义了其它的方法来释放非内存资源,但是其它人未必会调用该方法来释放。在finalize里面可以检查一下,如果没有释放就释放好了,晚释放总比不释放好。
5 即使对象的finalize已经运行了,不能保证该对象被销毁。要实现一些保证对象彻底被销毁时的动作,只能依赖于java.lang.ref里面的类和GC交互了。
参考
关于引用类型,GC,finalize的相互交互可以参考ReferenceQueue GC finalize Reference 测试及相关问题
评论
26 楼
随意而生
2015-03-13
学习学习了
25 楼
urfriend
2012-09-07
urfriend 写道
qwj528 写道
菜鸟问个问题。。。
A a = new A(new B("allen", 20));
a = null;
System.gc();
//这里执行了A的finalize()
C.a = this; 那么C.a就等于null
Thread.sleep(5000);
System.out.println(C.a.b); //这里应该出错啊!
A a = new A(new B("allen", 20));
a = null;
System.gc();
//这里执行了A的finalize()
C.a = this; 那么C.a就等于null
Thread.sleep(5000);
System.out.println(C.a.b); //这里应该出错啊!
菜鸟同问
囧,没注意到
@Override
public void finalize() {
System.out.println("A finalize");
C.a = this;
}
有个C.a = this;
24 楼
zhang_xzhi_xjtu
2012-09-07
为什么一定会失败?
对象复生了啊。
对象复生了啊。
23 楼
urfriend
2012-09-07
qwj528 写道
菜鸟问个问题。。。
A a = new A(new B("allen", 20));
a = null;
System.gc();
//这里执行了A的finalize()
C.a = this; 那么C.a就等于null
Thread.sleep(5000);
System.out.println(C.a.b); //这里应该出错啊!
A a = new A(new B("allen", 20));
a = null;
System.gc();
//这里执行了A的finalize()
C.a = this; 那么C.a就等于null
Thread.sleep(5000);
System.out.println(C.a.b); //这里应该出错啊!
菜鸟同问
22 楼
qwj528
2012-06-19
菜鸟问个问题。。。
A a = new A(new B("allen", 20));
a = null;
System.gc();
//这里执行了A的finalize()
C.a = this; 那么C.a就等于null
Thread.sleep(5000);
System.out.println(C.a.b); //这里应该出错啊!
A a = new A(new B("allen", 20));
a = null;
System.gc();
//这里执行了A的finalize()
C.a = this; 那么C.a就等于null
Thread.sleep(5000);
System.out.println(C.a.b); //这里应该出错啊!
21 楼
qwj528
2012-06-19
A a = new A(new B("allen", 20));
a = null;
System.gc();
Thread.sleep(5000);
System.out.println(C.a.b);
C.a = this;
a = null;
System.gc();
Thread.sleep(5000);
System.out.println(C.a.b);
C.a = this;
20 楼
e-beetle
2010-06-28
hi,哥们,xjtu在杭州啊,//hand
5 当一个对象在Unreachable+Unfinalized时,如果该对象使用的是默认的Object的finalize,或者虽然重写了,但是新的实现什么也不干。为了性能,GC可以把该对象之间变到Reclaimed状态直接销毁,而不用加入到F-Queue等待GC做进一步处理。
对第五点,有点疑问,开始我也认为应该是这样,但“虽然重写了,但是新的实现什么也不干”但我实际用jprofiler试了下,同样会进入queue的。
如果我override了finalize方法,里面什么也没有,还是可以看到有一堆的java.lang.Finalizer。
如果我没这个方法,就看不见java.lang.Finalizer了。能仔细说说这个的理论依据或出处吗?
谢谢
5 当一个对象在Unreachable+Unfinalized时,如果该对象使用的是默认的Object的finalize,或者虽然重写了,但是新的实现什么也不干。为了性能,GC可以把该对象之间变到Reclaimed状态直接销毁,而不用加入到F-Queue等待GC做进一步处理。
对第五点,有点疑问,开始我也认为应该是这样,但“虽然重写了,但是新的实现什么也不干”但我实际用jprofiler试了下,同样会进入queue的。
如果我override了finalize方法,里面什么也没有,还是可以看到有一堆的java.lang.Finalizer。
如果我没这个方法,就看不见java.lang.Finalizer了。能仔细说说这个的理论依据或出处吗?
谢谢
19 楼
zhang_xzhi_xjtu
2009-12-11
谢谢各位捧场
18 楼
zhao_xiao_dong
2009-12-10
确实写的很详细了,我明天再看一遍,争取把握住了
17 楼
erlengleng
2009-12-10
javaeye高手众多啊,此贴我认为不错,但是投新手的多
16 楼
wjm251
2009-10-20
呵呵,不错,看另一个解释
http://msdn.microsoft.com/en-us/library/aa244021(VS.60).aspx
When an object is first created (A), it is reachable and unfinalized.
As references to an object are discarded during program execution, an object that was reachable may become finalizer-reachable (B, C, D) or unreachable (E, F). (Note that a finalizer-reachable object never becomes unreachable directly; it becomes reachable when the finalizer from which it can be reached is invoked, as explained below.)
If the Java Virtual Machine detects that an unfinalized object has become finalizer-reachable or unreachable, it may label the object finalizable (G, H); moreover, if the object was unreachable, it becomes finalizer-reachable (H).
If the Java Virtual Machine detects that a finalized object has become unreachable, it may reclaim the storage occupied by the object because the object will never again become reachable (I).
At any time, a Java Virtual Machine may take any finalizable object, label it finalized, and then invoke its finalize method in some thread. This causes the object to become finalized and reachable (J, K), and it also may cause other objects that were finalizer-reachable to become reachable again (L, M, N).
A finalizable object cannot also be unreachable; it can be reached because its finalizer may eventually be invoked, whereupon the thread running the finalizer will have access to the object, as this (§15.7.2). Thus, there are actually only eight possible states for an object.
After an object has been finalized, no further action is taken until the automatic storage management determines that it is unreachable. Because of the way that an object progresses from the unfinalized state through the finalizable state to the finalized state, the finalize method is never automatically invoked more than once by a Java Virtual Machine for each object, even if the object is again made reachable after it has been finalized.
Explicit invocation of a finalizer ignores the current state of the object and does not change the state of the object from unfinalized or finalizable to finalized.
If a class does not override method finalize of class Object (or overrides it in only a trivial way, as described above), then if instances of such as class become unreachable, they may be discarded immediately rather than made to await a second determination that they have become unreachable. This strategy is indicated by the dashed arrow (O) in the transition diagram.
Java programmers should also be aware that a finalizer can be automatically invoked, even though it is reachable, during finalization-on-exit (§12.9); moreover, a finalizer can also be invoked explicitly as an ordinary method. Therefore, we recommend that the design of finalize methods be kept simple and that they be programmed defensively, so that they will work in all cases.
http://msdn.microsoft.com/en-us/library/aa244021(VS.60).aspx
When an object is first created (A), it is reachable and unfinalized.
As references to an object are discarded during program execution, an object that was reachable may become finalizer-reachable (B, C, D) or unreachable (E, F). (Note that a finalizer-reachable object never becomes unreachable directly; it becomes reachable when the finalizer from which it can be reached is invoked, as explained below.)
If the Java Virtual Machine detects that an unfinalized object has become finalizer-reachable or unreachable, it may label the object finalizable (G, H); moreover, if the object was unreachable, it becomes finalizer-reachable (H).
If the Java Virtual Machine detects that a finalized object has become unreachable, it may reclaim the storage occupied by the object because the object will never again become reachable (I).
At any time, a Java Virtual Machine may take any finalizable object, label it finalized, and then invoke its finalize method in some thread. This causes the object to become finalized and reachable (J, K), and it also may cause other objects that were finalizer-reachable to become reachable again (L, M, N).
A finalizable object cannot also be unreachable; it can be reached because its finalizer may eventually be invoked, whereupon the thread running the finalizer will have access to the object, as this (§15.7.2). Thus, there are actually only eight possible states for an object.
After an object has been finalized, no further action is taken until the automatic storage management determines that it is unreachable. Because of the way that an object progresses from the unfinalized state through the finalizable state to the finalized state, the finalize method is never automatically invoked more than once by a Java Virtual Machine for each object, even if the object is again made reachable after it has been finalized.
Explicit invocation of a finalizer ignores the current state of the object and does not change the state of the object from unfinalized or finalizable to finalized.
If a class does not override method finalize of class Object (or overrides it in only a trivial way, as described above), then if instances of such as class become unreachable, they may be discarded immediately rather than made to await a second determination that they have become unreachable. This strategy is indicated by the dashed arrow (O) in the transition diagram.
Java programmers should also be aware that a finalizer can be automatically invoked, even though it is reachable, during finalization-on-exit (§12.9); moreover, a finalizer can also be invoked explicitly as an ordinary method. Therefore, we recommend that the design of finalize methods be kept simple and that they be programmed defensively, so that they will work in all cases.
15 楼
zhang_xzhi_xjtu
2009-10-19
patrickyao1988 写道
zhang_xzhi_xjtu 写道
考虑如下场景:
A有一个B的引用。然后A变成垃圾,有待回收。在GC的作用下,A和B被加入F-QUEUE。
这种场景下,B在其他地方应该没有强引用吧?
恩。
zhang_xzhi_xjtu 写道
A和B都是F-Reachable+Finalizable。
当回收A时,A从F-Reachable+Finalizable变到Reachable+Finalized。但是B此时还是在F-QUEUE的,B的状态变成Reachable+Finalizable(因为A的状态为Reachable)。
这样的话,A是经历了F-Reachable+Finalizable,得以从Reachable+Finalizable发展到Reachable+Finalized的吧,那最后那个B
zhang_xzhi_xjtu 写道
以后GC回收B的时候B的状态就从Reachable+Finalizable变为Reachable+Finalized。
是不是也要经历F-Reachable+Finalizable这个状态,直接从这两个状态切换可以吗?
麻烦楼主了!感激不尽
B刚开始是在F-Reachable+Finalizable,然后因为A的关系跳到Reachable+Finalizable,GC对其回收的时候跳到Reachable+Finalized。
14 楼
patrickyao1988
2009-10-16
zhang_xzhi_xjtu 写道
考虑如下场景:
A有一个B的引用。然后A变成垃圾,有待回收。在GC的作用下,A和B被加入F-QUEUE。
这种场景下,B在其他地方应该没有强引用吧?
zhang_xzhi_xjtu 写道
A和B都是F-Reachable+Finalizable。
当回收A时,A从F-Reachable+Finalizable变到Reachable+Finalized。但是B此时还是在F-QUEUE的,B的状态变成Reachable+Finalizable(因为A的状态为Reachable)。
这样的话,A是经历了F-Reachable+Finalizable,得以从Reachable+Finalizable发展到Reachable+Finalized的吧,那最后那个B
zhang_xzhi_xjtu 写道
以后GC回收B的时候B的状态就从Reachable+Finalizable变为Reachable+Finalized。
是不是也要经历F-Reachable+Finalizable这个状态,直接从这两个状态切换可以吗?
麻烦楼主了!感激不尽
13 楼
zhang_xzhi_xjtu
2009-10-16
patrickyao1988 写道
楼主我想问下第一行第二第三个图,就是Reachable+Finalizable怎么变到Reachable+Finalized的?
考虑如下场景:
A有一个B的引用。然后A变成垃圾,有待回收。在GC的作用下,A和B被加入F-QUEUE。
A和B都是F-Reachable+Finalizable。
当回收A时,A从F-Reachable+Finalizable变到Reachable+Finalized。但是B此时还是在F-QUEUE的,B的状态变成Reachable+Finalizable(因为A的状态为Reachable)。
以后GC回收B的时候B的状态就从Reachable+Finalizable变为Reachable+Finalized。
12 楼
zhang_xzhi_xjtu
2009-10-16
patrickyao1988 写道
额 有点混
楼主的意思是被标记为Finalized之后就不会把它再放入F-Queue了吧?
上面说的是"finalizer-reachable 是除了reachable外,从F-Queue可以通过引用到达的对象。"但finalizer-reachable状态并不是指就在F-Queue的,比如finalizer-reachable+Finalized。楼主这样理解可对?
楼主的意思是被标记为Finalized之后就不会把它再放入F-Queue了吧?
上面说的是"finalizer-reachable 是除了reachable外,从F-Queue可以通过引用到达的对象。"但finalizer-reachable状态并不是指就在F-Queue的,比如finalizer-reachable+Finalized。楼主这样理解可对?
对
11 楼
patrickyao1988
2009-10-16
楼主我想问下第一行第二第三个图,就是Reachable+Finalizable怎么变到Reachable+Finalized的?
10 楼
patrickyao1988
2009-10-16
额 有点混
楼主的意思是被标记为Finalized之后就不会把它再放入F-Queue了吧?
上面说的是"finalizer-reachable 是除了reachable外,从F-Queue可以通过引用到达的对象。"但finalizer-reachable状态并不是指就在F-Queue的,比如finalizer-reachable+Finalized。楼主这样理解可对?
楼主的意思是被标记为Finalized之后就不会把它再放入F-Queue了吧?
上面说的是"finalizer-reachable 是除了reachable外,从F-Queue可以通过引用到达的对象。"但finalizer-reachable状态并不是指就在F-Queue的,比如finalizer-reachable+Finalized。楼主这样理解可对?
9 楼
zhang_xzhi_xjtu
2009-10-15
wjm251 写道
6 从状态图看出,不管怎么折腾,任意一个对象的finalize只至多执行一次,一旦对象变为Finalized,就怎么也不会在回到F-Queue去了。
看右上角那两个图,上一个指向下一个得箭头就是这种情况:
上一个是Finalized,下一个图F-Queue
看右上角那两个图,上一个指向下一个得箭头就是这种情况:
上一个是Finalized,下一个图F-Queue
下一个不是F queue啊。下一个是F-Reachable+Finalized.
进入F-Queue的状态是F-Reachable+Finalizable。
8 楼
wjm251
2009-10-15
自己抠一下
6 从状态图看出,不管怎么折腾,任意一个对象的finalize只至多执行一次,一旦对象变为Finalized,就怎么也不会在回到F-Queue去了。
看右上角那两个图,上一个指向下一个得箭头就是这种情况:
上一个是Finalized,下一个图F-Queue
6 从状态图看出,不管怎么折腾,任意一个对象的finalize只至多执行一次,一旦对象变为Finalized,就怎么也不会在回到F-Queue去了。
看右上角那两个图,上一个指向下一个得箭头就是这种情况:
上一个是Finalized,下一个图F-Queue
7 楼
patrickyao1988
2009-10-15
楼主我又来顶你的文章了。。草草看了第一遍,有些部分看的迷糊,再看一下。。。。
发表评论
-
java对象的大小_基础知识
2014-09-14 16:51 1774引言 Java的对象被jvm管理,单个对象如何布局,大小如何, ... -
xml encoding和实际编码不同导致xml解析异常
2014-04-10 09:52 5010发现一个xml encoding和实际编码不同导致xml解析异 ... -
按照bit读取或写入java的IO流
2012-11-18 22:00 3803写了个按照bit读取或写入java的IO流的简单代码,保留在博 ... -
类构造函数clinit尽量简单化
2012-01-29 16:30 1411java的类构造方法只能执行一次(不考虑多个类加载器和类卸载的 ... -
使用ImageIO.write存储png格式图片性能较差问题
2011-12-27 19:06 29334目前加载一个png格式的图片,做一些绘图工作,发现ImageI ... -
GC iCMS一次调优
2011-12-23 20:00 0原有GC参数: -server -XX:+UseParNew ... -
java集合框架类源代码阅读体会(Java Collections Framework)
2011-09-17 23:55 5037忘了什么原因突然想看下JCF,于是就有了这个阅读体会。 jav ... -
[gc] GC调优及awk脚本分析GC日志
2011-07-20 19:26 2134原有GC参数 JAVA_OPTS="-server ... -
jvm性能查看工具
2011-06-18 11:48 1606jps查看所有java进程。 jconsole jvisu ... -
[gc] java内存管理以及GC
2011-03-27 13:25 4476目录 内存管理简介 GC简介 好的Collector的特性 ... -
object的hash code
2011-01-03 19:40 2129sun的jvm默认的hash code返回的是对象的内部地址构 ... -
Enum简介
2010-08-16 21:51 1518java的Enum不同于c的命名整型常量,它本身是有类型的,而 ... -
java1.5中{@inheritDoc}的使用
2010-07-12 23:14 9606java1.5中@Override还不能用 ... -
[code] 大量只读线程安全的FastHashMap
2010-06-25 17:27 2325org.apache.commons.collections. ... -
[code] 继承TableRowSorter的一个小陷阱
2010-01-09 21:54 1295在一个JTable里面想做sorting。 继承了TableR ... -
[code] 多个线程写入,单线程读出的Stream对
2009-11-06 10:38 1739今天想做一个System.out的重定向,想要得的结果是有很多 ... -
深入理解java的clone
2009-10-09 14:13 4674目录 预备知识 为什么 ... -
简明OPhone/Android入门体验(有图有源码)
2009-09-25 00:34 3368主要参考 http://code.google.com/p/a ... -
深入理解ReferenceQueue GC finalize Reference
2009-06-22 22:55 20242关于对象如何销毁以及f ...
相关推荐
深入理解 `final` 关键字可以帮助开发者写出更加安全、高效的代码。 首先,`final` 关键字可以用于声明变量。当一个变量被声明为 `final` 时,它的值一旦被赋值后就不能再改变。这适用于成员变量、局部变量以及静态...
Java编程中的`final`、`finally`和`finalize`关键字对于理解Java程序的运行机制至关重要。它们各自有独特的用途和特点。 首先,`final`关键字是Java中的一个多面手,它可以用于修饰类、方法和变量。当`final`用于...
深入理解 Java 虚拟机笔记 Java 虚拟机(JVM)是 Java 语言的运行环境,它负责解释和执行 Java 字节码。下面是 Java 虚拟机相关的知识点: 虚拟机内存结构 Java 虚拟机的内存结构主要包括以下几个部分: * 方法...
第2章 深入理解Java Binder和MessageQueue 2.1 概述 2.2 Java层中的Binder架构分析 2.2.1 Binder架构总览 2.2.2 初始化Java层Binder框架 2.2.3 addService实例分析 2.2.4 Java层Binder架构总结 2.3 心系两界...
本篇文章将深入探讨`finalize()`方法的原理、问题以及替代方案。 1. `finalize()`方法的定义: `finalize()`方法是Java中的一个虚方法,它的设计初衷是为了在对象被垃圾收集器回收前提供最后一次清理机会。程序员...
Java垃圾收集(GC)机制是Java编程中...理解Java的GC机制有助于优化程序性能,避免因内存管理不当引起的系统不稳定。开发者应根据应用需求选择合适的垃圾收集策略,并注意合理使用各种引用类型,避免不必要的内存占用。
深入理解 final、finally、finalize 浅拷贝和深拷贝 关于四种引用类型 Java 开发最容易忽视的 10 个 Bug Java 浅拷贝和深拷贝 Java 创建对象的五种方式 Exception 和 Error 的区别 for 、foreach 、iterator 三种...
本文将深入探讨这个包中的四种主要引用类型:StrongReference、SoftReference、WeakReference 和 PhantomReference,以及它们的特性、用法和作用。 首先,强引用(StrongReference)是我们在日常编程中最常见的引用...
理解Java垃圾回收机制对于编写高效、健壮的Java程序至关重要。开发者需要了解垃圾回收的工作原理,避免产生内存泄漏,并合理调整垃圾回收参数以适应应用程序的需求。在实际开发中,结合内存分析工具(如VisualVM、...
深入理解这些概念对于编写高效、健壮的Java代码至关重要。 ### final 1. **不可变性**:`final` 关键字用于声明一个变量、方法或类为最终状态,意味着一旦赋值或定义后,其值或状态不能被修改。例如,当一个变量被...
### Java初学者必看:深入理解Java垃圾回收机制 对于Java初学者而言,理解Java的垃圾回收机制(Garbage Collection, GC)是非常重要的。在C++等其他编程语言中,程序员需要手动管理内存,比如使用new分配内存后,还...
例如《Thinking in Java》、《Java核心技术卷》以及Oracle的Java教程,都是深入理解Java的好资源。 通过系统地学习这些知识点,你将能够全面掌握Java JDK 6.0,并为未来的Java开发工作打下坚实的基础。随着技术的...
Java是世界上最流行的...通过深入理解JVM的结构、`finalize`机制以及GC的工作方式,开发者能够更好地优化Java应用程序的性能,预防和解决内存问题。这不仅是Java程序员的基础知识,也是进阶为高级开发者的关键技能。
《Java编程思想》提供了关于对象入门、类继承以及接口等基础和高级特性的讲解,而《深入理解Java虚拟机》则深入讲解了垃圾收集器、内存分配策略以及JVM内部的工作机制。 Spring框架是Java企业级应用开发中最重要的...
理解Java垃圾回收机制及其与内存泄漏的关系对于编写高效、稳定的Java应用程序至关重要。开发人员应该尽量遵循最佳实践,避免过度依赖垃圾回收,而是积极地管理自己的内存使用,以减少潜在的性能问题和内存泄漏风险。
### 深入Java虚拟机移植 #### Java虚拟机概念 Java虚拟机(JVM, Java Virtual Machine)作为Java技术的核心组件之一,在实现Java程序跨平台特性方面扮演着至关重要的角色。它是一种抽象的计算机模型,能够理解并...
#### 深入理解Java的关键概念 然而,Java的强大之处并不止于表面,深入到其核心,有诸多隐微细节等待探索。例如,对象创建和初始化过程中的细微差别,如何正确实现`Cloneable`和`Serializable`接口,以及`equals`...
8. **《深入理解Java虚拟机》**:周志明的著作,详细解析了JVM的工作原理,包括内存管理、类加载机制、性能优化等。 9. **《Java性能优化权威指南》**:通过实际案例分析Java性能问题,提供了解决方案和调优技巧。 ...
### Java入门——深入理解Java语言回收机制 #### 一、垃圾回收(Garbage Collection)概述 在编程领域,特别是对于初学者来说,了解并掌握Java的垃圾回收机制是非常重要的。与C++等需要手动管理内存的语言不同,...