org.eclipse.mat.snapshot.MultiplePathsFromGCRootsClassRecord Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of haha Show documentation
Show all versions of haha Show documentation
Java library to automate the analysis of Android heap dumps.
/**
* ****************************************************************************
* Copyright (c) 2008 SAP AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* SAP AG - initial API and implementation
* *****************************************************************************
*/
package org.eclipse.mat.snapshot;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import org.eclipse.mat.SnapshotException;
import org.eclipse.mat.collect.HashMapIntObject;
import org.eclipse.mat.collect.SetInt;
import org.eclipse.mat.snapshot.model.IClass;
public class MultiplePathsFromGCRootsClassRecord {
private List paths = new ArrayList();
private SetInt distinctObjects;
private int level;
private IClass clazz;
private long referencedSize = -1;
private ISnapshot snapshot;
private boolean fromRoots;
public MultiplePathsFromGCRootsClassRecord(IClass clazz, int level, boolean fromRoots,
ISnapshot snapshot) {
this.clazz = clazz;
this.level = level;
this.fromRoots = fromRoots;
this.snapshot = snapshot;
}
public MultiplePathsFromGCRootsClassRecord[] nextLevel() throws SnapshotException {
int nextLevel = level + 1;
if (nextLevel < 0) return null;
HashMapIntObject nextLevelRecords =
new HashMapIntObject();
for (int[] path : paths) {
if (path != null) {
int newIndex = fromRoots ? path.length - nextLevel - 1 : nextLevel;
// check if one of the ends is reached
if (newIndex < 0 || newIndex >= path.length) {
continue;
}
IClass clazz = snapshot.getClassOf(path[newIndex]);
MultiplePathsFromGCRootsClassRecord record = nextLevelRecords.get(clazz.getObjectId());
if (record == null) {
record = new MultiplePathsFromGCRootsClassRecord(clazz, nextLevel, fromRoots, snapshot);
nextLevelRecords.put(clazz.getObjectId(), record);
}
record.addPath(path);
}
}
return nextLevelRecords.getAllValues(new MultiplePathsFromGCRootsClassRecord[0]);
}
/**
* This method is used only when the record is built. Adds one path to the
* set of paths
*/
public void addPath(int[] path) {
paths.add(path);
}
/**
* Get all the paths going through the object (getObjectId())
*
* @return List each element in the list is an int[] representing a
* path
*/
public List getPaths() {
return paths;
}
/**
* Get the number of paths going through this object
*/
public int getCount() {
return paths.size();
}
/**
* Get the number of distinct objects of this class
*/
public int getDistinctCount() {
if (distinctObjects == null) // lazy init
{
distinctObjects = new SetInt();
for (int[] path : paths) {
int index = fromRoots ? path.length - level - 1 : level;
distinctObjects.add(path[index]);
}
}
return distinctObjects.size();
}
/**
* Get the total net heap size of all referenced objects (see
* getReferencedObjects())
*
* @return - the total heap size of all referenced objects
* @throws SnapshotException
*/
public long getReferencedHeapSize() throws SnapshotException {
if (referencedSize == -1) {
referencedSize = snapshot.getHeapSize(getReferencedObjects());
}
return referencedSize;
}
/**
* Get the "end" objects for each path. This is equal to getting all the
* paths and looking at their element [0]
*
* @return - an array with all the objects at the end of the paths
*/
public int[] getReferencedObjects() {
int[] result = new int[paths.size()];
int i = 0;
for (int[] path : paths) {
result[i++] = path[0];
}
return result;
}
public static Comparator getComparatorByNumberOfReferencedObjects() {
return new Comparator() {
public int compare(MultiplePathsFromGCRootsClassRecord o1,
MultiplePathsFromGCRootsClassRecord o2) {
if (o1.paths.size() < o2.paths.size()) return 1;
if (o1.paths.size() > o2.paths.size()) return -1;
return 0;
}
};
}
/**
* Returns a Comparator ordering the records descending by the total size of
* referenced objects.
*/
public static Comparator getComparatorByReferencedHeapSize() {
return new Comparator() {
public int compare(MultiplePathsFromGCRootsClassRecord o1,
MultiplePathsFromGCRootsClassRecord o2) {
try {
if (o1.getReferencedHeapSize() < o2.getReferencedHeapSize()) return 1;
if (o1.getReferencedHeapSize() > o2.getReferencedHeapSize()) return -1;
return 0;
} catch (SnapshotException e) {
// $JL-EXC$
return 0;
}
}
};
}
public IClass getClazz() {
return clazz;
}
public boolean isFromRoots() {
return fromRoots;
}
public int getLevel() {
return level;
}
}