org.netbeans.lib.profiler.heap.NearestGCRoot Maven / Gradle / Ivy
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.lib.profiler.heap;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
*
* @author Tomas Hurka
*/
class NearestGCRoot {
//~ Static fields/initializers -----------------------------------------------------------------------------------------------
private static final int BUFFER_SIZE = (64 * 1024) / 8;
private static final String[] REF_CLASSES = {
"java.lang.ref.WeakReference", // NOI18N
"java.lang.ref.SoftReference", // NOI18N
"java.lang.ref.FinalReference", // NOI18N
"java.lang.ref.PhantomReference" // NOI18N
};
private static final String JAVA_LANG_REF_REFERENCE = "java.lang.ref.Reference"; // NOI18N
private static final String REFERENT_FILED_NAME = "referent"; // NOI18N
private static final String SVM_REFFERENCE = "com.oracle.svm.core.heap.heapImpl.DiscoverableReference"; // NOI18N
private static final String SVM_REFERENT_FILED_NAME = "rawReferent"; // NOI18N
//~ Instance fields ----------------------------------------------------------------------------------------------------------
private Field referentFiled;
private HprofHeap heap;
private LongBuffer readBuffer;
private LongBuffer writeBuffer;
private LongBuffer leaves;
private LongBuffer multipleParents;
private Set referenceClasses;
private boolean gcRootsComputed;
private long allInstances;
private long processedInstances;
//private long leavesCount;
//private long firstLevel;
//private long multiParentsCount;
//~ Constructors -------------------------------------------------------------------------------------------------------------
NearestGCRoot(HprofHeap h) {
heap = h;
}
//~ Methods ------------------------------------------------------------------------------------------------------------------
Instance getNearestGCRootPointer(Instance instance) {
if (heap.getGCRoot(instance) != null) {
return instance;
}
computeGCRoots();
long nextGCPathId = heap.idToOffsetMap.get(instance.getInstanceId()).getNearestGCRootPointer();
return heap.getInstanceByID(nextGCPathId);
}
private boolean isSpecialReference(FieldValue value, Instance instance) {
Field f = value.getField();
return f.equals(referentFiled) && referenceClasses.contains(instance.getJavaClass());
}
private synchronized void computeGCRoots() {
if (gcRootsComputed) {
return;
}
Progress.Handle handle = Progress.COMPUTE_GC_ROOTS.start();
if (!initHotSpotReference()) {
if (!initSVMReference()) {
throw new IllegalArgumentException("reference field not found"); // NOI18N
}
}
heap.computeReferences(); // make sure references are computed first
allInstances = heap.getSummary().getTotalLiveInstances();
Set processedClasses = new HashSet(heap.getAllClasses().size()*4/3);
try {
createBuffers();
fillZeroLevel();
do {
switchBuffers();
computeOneLevel(processedClasses, handle);
} while (hasMoreLevels());
} catch (IOException ex) {
Systems.printStackTrace(ex);
}
deleteBuffers();
heap.idToOffsetMap.flush();
gcRootsComputed = true;
heap.writeToFile();
handle.close();
}
private boolean initHotSpotReference() {
referentFiled = computeReferentFiled(JAVA_LANG_REF_REFERENCE, REFERENT_FILED_NAME);
if (referentFiled != null) {
referenceClasses = new HashSet();
for (int i=0; i= REF_CLASSES.length;
}
return false;
}
private boolean initSVMReference() {
referentFiled = computeReferentFiled(SVM_REFFERENCE, SVM_REFERENT_FILED_NAME);
if (referentFiled != null) {
JavaClass ref = referentFiled.getDeclaringClass();
referenceClasses = new HashSet();
referenceClasses.add(ref);
referenceClasses.addAll(ref.getSubClasses());
return !referenceClasses.isEmpty();
}
return false;
}
private void computeOneLevel(Set processedClasses, Progress.Handle handle) throws IOException {
int idSize = heap.dumpBuffer.getIDSize();
for (;;) {
Instance instance;
long instanceOffset = readLong();
List fieldValues;
Iterator valuesIt;
boolean hasValues = false;
if (instanceOffset == 0L) { // end of level
break;
}
handle.progress(processedInstances++,allInstances);
instance = heap.getInstanceByOffset(new long[] {instanceOffset});
if (instance instanceof ObjectArrayInstance) {
ObjectArrayDump array = (ObjectArrayDump) instance;
int size = array.getLength();
long offset = array.getOffset();
long instanceId = instance.getInstanceId();
for (int i=0;i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy