Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java
41161 views
1
/*
2
* Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
package sun.jvm.hotspot.tools;
26
27
import sun.jvm.hotspot.debugger.JVMDebugger;
28
29
import sun.jvm.hotspot.oops.*;
30
import sun.jvm.hotspot.utilities.SystemDictionaryHelper;
31
32
import java.util.ArrayList;
33
import java.util.Collections;
34
import java.util.Comparator;
35
import java.util.HashMap;
36
37
/*
38
* Iterates over the queue of object pending finalization and prints a
39
* summary of these objects in the form of a histogram.
40
*/
41
public class FinalizerInfo extends Tool {
42
43
public FinalizerInfo() {
44
super();
45
}
46
47
public FinalizerInfo(JVMDebugger d) {
48
super(d);
49
}
50
51
@Override
52
public String getName() {
53
return "finalizerInfo";
54
}
55
56
public static void main(String[] args) {
57
FinalizerInfo finfo = new FinalizerInfo();
58
finfo.execute(args);
59
}
60
61
public void run() {
62
/*
63
* The implementation here has a dependency on the implementation of
64
* java.lang.ref.Finalizer. If the Finalizer implementation changes it's
65
* possible this method will require changes too. We looked into using
66
* ObjectReader to deserialize the objects from the target VM but as
67
* there aren't any public methods to traverse the queue it means using
68
* reflection which will also tie us to the implementation.
69
*
70
* The assumption here is that Finalizer.queue is the ReferenceQueue
71
* with the objects awaiting finalization. The ReferenceQueue queueLength
72
* is the number of objects in the queue, and 'head' is the head of the
73
* queue.
74
*/
75
InstanceKlass ik =
76
SystemDictionaryHelper.findInstanceKlass("java.lang.ref.Finalizer");
77
final Oop[] queueref = new Oop[1];
78
ik.iterateStaticFields(new DefaultOopVisitor() {
79
public void doOop(OopField field, boolean isVMField) {
80
String name = field.getID().getName();
81
if (name.equals("queue")) {
82
queueref[0] = field.getValue(getObj());
83
}
84
}
85
});
86
Oop queue = queueref[0];
87
88
InstanceKlass k = (InstanceKlass) queue.getKlass();
89
90
LongField queueLengthField = (LongField) k.findField("queueLength", "J");
91
long queueLength = queueLengthField.getValue(queue);
92
93
OopField headField = (OopField) k.findField("head", "Ljava/lang/ref/Reference;");
94
Oop head = headField.getValue(queue);
95
96
System.out.println("Number of objects pending for finalization: " + queueLength);
97
98
/*
99
* If 'head' is non-NULL then it is the head of a list of References.
100
* We iterate over the list (end of list is when head.next == head)
101
*/
102
if (head != null) {
103
k = (InstanceKlass) head.getKlass();
104
OopField referentField =
105
(OopField) k.findField("referent", "Ljava/lang/Object;");
106
OopField nextField =
107
(OopField) k.findField("next", "Ljava/lang/ref/Reference;");
108
109
HashMap<Klass, ObjectHistogramElement> map = new HashMap<>();
110
for (;;) {
111
Oop referent = referentField.getValue(head);
112
113
Klass klass = referent.getKlass();
114
if (!map.containsKey(klass)) {
115
map.put(klass, new ObjectHistogramElement(klass));
116
}
117
map.get(klass).updateWith(referent);
118
119
Oop next = nextField.getValue(head);
120
if (next == null || next.equals(head)) break;
121
head = next;
122
}
123
124
/*
125
* Sort results - decending order by total size
126
*/
127
ArrayList<ObjectHistogramElement> list = new ArrayList<>();
128
list.addAll(map.values());
129
Collections.sort(list, new Comparator<>() {
130
public int compare(ObjectHistogramElement o1, ObjectHistogramElement o2) {
131
return o1.compare(o2);
132
}
133
});
134
135
/*
136
* Print summary of objects in queue
137
*/
138
System.out.println("");
139
System.out.println("Count" + "\t" + "Class description");
140
System.out.println("-------------------------------------------------------");
141
for (int i=0; i<list.size(); i++) {
142
ObjectHistogramElement e = (ObjectHistogramElement)list.get(i);
143
System.out.println(e.getCount() + "\t" + e.getDescription());
144
}
145
}
146
147
}
148
}
149
150