jdk源码解析--Finalizer类
Posted 我的IT技术路
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jdk源码解析--Finalizer类相关的知识,希望对你有一定的参考价值。
在之前几篇内容中,我们介绍了java几种引用,并深入解释软引用和弱引用的功能,通过引用缓存来说明了这两个引用在实际中的作用。本文我们将介绍java引用的最后一点内容Finalizer。Finalizer这个在实际上也不常使用,不过在面试的时候会经常被问到Finalizer和finally的关系。说实在的,这两个根本没啥关系呀,Finalizer是jvm内存内容中的一个实现类,而finally是java的一个关键字,该关键字一般在异常捕获中使用,一般常和try/catch等联合使用。Finally之前在java关键字的介绍的时候有提到到,本文中点讲述一下Finalizer类的实现和使用。
首先明确一下:Finalizer类的作用是什么?Finalizer是一个类清除时候的一些资源清理收尾工作,它一般在适当的时候被JVM调用。在effect java中明确有一点说明Finalizer方法:避免使用终结方法和清除方法。终结方法就是本文说的Finalizer方法,清除方法是java9中实现的用来替换java8 的终结方法。虽然 java9希望清除对象时没那么危险,但是依然是不希望被使用的。终结方法的使用有以下几个问题:
1) 行为的不稳定
2) 降低性能
3) 可移植性问题
以上的说明只想告诉读者,在一般情况下不要使用终结方法,但这并不影响我们看下这个类的源码是怎么实现的,如下为实现的类图。
我们先看下其父类的实现,就一个构造函数,jdk明确表示该类就是为了实现Finalizer类的:
1. class FinalReference<T> extends Reference<T> {
2.
3. public FinalReference(T referent, ReferenceQueue<? super T> q) {
4. super(referent, q);
5. }
6. }
Finalizer类的代码:
1. final class Finalizer extends FinalReference<Object> { //常量
2.
3. private static ReferenceQueue<Object> queue = new ReferenceQueue<>();//定义一个引用队列
4. private static Finalizer unfinalized = null;//定义一个未初始化的类
5. private static final Object lock = new Object();//锁对象
6.
7. private Finalizer
8. next = null,//常引用队列的前一个
9. prev = null;//常引用队列的后一个
10.
11. private boolean hasBeenFinalized() {//是否初始化
12. return (next == this);
13. }
14.
15. private void add() {//添加当前元素到常量队列中
16. synchronized (lock) {//加锁
17. if (unfinalized != null) {
18. this.next = unfinalized;
19. unfinalized.prev = this;
20. }
21. unfinalized = this;
22. }
23. }
24.
25. private void remove() {//删除常量队列中当前元素
26. synchronized (lock) {
27. if (unfinalized == this) {
28. if (this.next != null) {
29. unfinalized = this.next;
30. } else {
31. unfinalized = this.prev;
32. }
33. }
34. if (this.next != null) {
35. this.next.prev = this.prev;
36. }
37. if (this.prev != null) {
38. this.prev.next = this.next;
39. }
40. this.next = this; //确保当前被初始化
41. this.prev = this;
42. }
43. }
44.
45. private Finalizer(Object finalizee) {//构造函数,传入对象
46. super(finalizee, queue);
47. add();//添加到序列中
48. }
49.
50. /* Invoked by VM */
51. static void register(Object finalizee) {//注册到jvm中
52. new Finalizer(finalizee);
53. }
54.
55. private void runFinalizer(JavaLangAccess jla) {
56. synchronized (this) {//加锁,this锁
57. if (hasBeenFinalized()) return;//已经初始化的直接返回
58. remove();//否则删除
59. }
60. try {
61. Object finalizee = this.get();
62. if (finalizee != null && !(finalizee instanceof java.lang.Enum)) {
63. jla.invokeFinalize(finalizee);//执行终结方法
64.
65. /* Clear stack slot containing this variable, to decrease
66. the chances of false retention with a conservative GC */
67. finalizee = null;
68. }
69. } catch (Throwable x) { }
70. super.clear();
71. }
72.
73.
74. private static void forkSecondaryFinalizer(final Runnable proc) {//创建另一个特殊功能辅助终结器,该方法被runFinalization 和 runFinalizersOnExit调用
75. AccessController.doPrivileged(
76. new PrivilegedAction<Void>() {
77. public Void run() {
78. ThreadGroup tg = Thread.currentThread().getThreadGroup();
79. for (ThreadGroup tgn = tg;
80. tgn != null;
81. tg = tgn, tgn = tg.getParent());
82. Thread sft = new Thread(tg, proc, "Secondary finalizer");
83. sft.start();
84. try {
85. sft.join();//等待
86. } catch (InterruptedException x) {
87. /* Ignore */
88. }
89. return null;
90. }});
91. }
92.
93. /* Called by Runtime.runFinalization() */
94. static void runFinalization() {//虚拟机执行
95. if (!VM.isBooted()) {
96. return;
97. }
98.
99. forkSecondaryFinalizer(new Runnable() {
100. private volatile boolean running;
101. public void run() {
102. if (running)
103. return;
104. final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
105. running = true;
106. for (;;) {
107. Finalizer f = (Finalizer)queue.poll();
108. if (f == null) break;
109. f.runFinalizer(jla);
110. }
111. }
112. });
113. }
114.
115. /* Invoked by java.lang.Shutdown */
116. static void runAllFinalizers() {//java虚拟机要关闭的时候,
117. if (!VM.isBooted()) {
118. return;
119. }
120.
121. forkSecondaryFinalizer(new Runnable() {
122. private volatile boolean running;
123. public void run() {
124. if (running)
125. return;
126. final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
127. running = true;
128. for (;;) {
129. Finalizer f;
130. synchronized (lock) {
131. f = unfinalized;
132. if (f == null) break;
133. unfinalized = f.next;
134. }
135. f.runFinalizer(jla);//依次执行删除方法
136. }}});
137. }
138.
139. private static class FinalizerThread extends Thread {
140. private volatile boolean running;//是否运行,使用volatile保证可见性
141. FinalizerThread(ThreadGroup g) {
142. super(g, "Finalizer");
143. }
144. public void run() {
145. if (running)
146. return;
147.
148. // Finalizer thread starts before System.initializeSystemClass
149. // is called. Wait until JavaLangAccess is available
150. while (!VM.isBooted()) {//如果jvm还没启动,等待
151. // delay until VM completes initialization
152. try {
153. VM.awaitBooted();
154. } catch (InterruptedException x) {
155. // ignore and continue
156. }
157. }
158. final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();//获取
159. running = true;
160. for (;;) {
161. try {
162. Finalizer f = (Finalizer)queue.remove();//移除队列的元素
163. f.runFinalizer(jla);//执行终结的方法
164. } catch (InterruptedException x) {
165. // ignore and continue
166. }
167. }
168. }
169. }
170.
171. static {
172. ThreadGroup tg = Thread.currentThread().getThreadGroup();
173. for (ThreadGroup tgn = tg;
174. tgn != null;
175. tg = tgn, tgn = tg.getParent());
176. Thread finalizer = new FinalizerThread(tg);//初始化终结线程
177. finalizer.setPriority(Thread.MAX_PRIORITY - 2);
178. finalizer.setDaemon(true);
179. finalizer.start();
180. }
181.
182. }
好吧,看完代码之后还是要提醒一下,一般不用终结器。
以上是关于jdk源码解析--Finalizer类的主要内容,如果未能解决你的问题,请参考以下文章
jdk源码解析--AbstractStringBuilder类