in analysis/heap-dump/impl/src/main/java/org/eclipse/jifa/hda/impl/HeapDumpAnalyzerImpl.java [1655:1811]
public PageView<Model.Histogram.Item> getChildrenOfHistogram(Model.Histogram.Grouping groupBy, int[] ids,
String sortBy, boolean ascendingOrder,
int parentObjectId, int page, int pageSize) {
return $(() -> {
Map<String, Object> args = new HashMap<>();
if (ids != null) {
args.put("objects", Helper.buildHeapObjectArgument(ids));
}
IResult result = queryByCommand(context, "histogram -groupBy " + groupBy.name(), args);
switch (groupBy) {
case BY_CLASS: {
throw new AnalysisException("Should not reach here");
}
case BY_CLASSLOADER: {
Histogram.ClassLoaderTree tree = (Histogram.ClassLoaderTree) result;
List<?> elems = tree.getElements();
List<? extends ClassHistogramRecord> children = null;
for (Object elem : elems) {
if (elem instanceof XClassLoaderHistogramRecord) {
if (((XClassLoaderHistogramRecord) elem).getClassLoaderId() == parentObjectId) {
children = (List<? extends ClassHistogramRecord>) ((XClassLoaderHistogramRecord) elem)
.getClassHistogramRecords();
break;
}
}
}
if (children != null) {
return PageViewBuilder.<ClassHistogramRecord, Model.Histogram.Item>fromList(
(List<ClassHistogramRecord>) children)
.beforeMap(record -> $(() -> record
.calculateRetainedSize(context.snapshot, true, true, Helper.VOID_LISTENER)))
.paging(new PagingRequest(page, pageSize))
.map(record -> new Model.Histogram.Item(record.getClassId(), record.getLabel(),
Model.Histogram.ItemType.CLASS,
record.getNumberOfObjects(),
record.getUsedHeapSize(),
record.getRetainedHeapSize()))
.sort(Model.Histogram.Item.sortBy(sortBy, ascendingOrder))
.done();
} else {
return PageView.empty();
}
}
case BY_SUPERCLASS: {
Histogram.SuperclassTree st = (Histogram.SuperclassTree) result;
List<?> children = new ExoticTreeFinder(st)
.setGetChildrenCallback(node -> {
Map<String, ?> subClasses = ReflectionUtil.getFieldValueOrNull(node, "subClasses");
if (subClasses != null) {
return new ArrayList<>(subClasses.values());
}
return null;
})
.setPredicate((theTree, theNode) -> theTree.getContext(theNode).getObjectId())
.findChildrenOf(parentObjectId);
if (children != null) {
return PageViewBuilder.<HistogramRecord, Model.Histogram.Item>fromList(
(List<HistogramRecord>) children)
.paging(new PagingRequest(page, pageSize))
.map(e -> {
Model.Histogram.Item item = new Model.Histogram.Item();
int objectId = st.getContext(e).getObjectId();
item.setType(Model.Histogram.ItemType.SUPER_CLASS);
item.setObjectId(objectId);
item.setLabel((String) st.getColumnValue(e, 0));
item.setNumberOfObjects((Long) st.getColumnValue(e, 1));
item.setShallowSize(((Bytes) st.getColumnValue(e, 2)).getValue());
return item;
})
.sort(Model.Histogram.Item.sortBy(sortBy, ascendingOrder))
.done();
} else {
return PageView.empty();
}
}
case BY_PACKAGE: {
Histogram.PackageTree pt = (Histogram.PackageTree) result;
Object targetParentNode = new ExoticTreeFinder(pt)
.setGetChildrenCallback(node -> {
Map<String, ?> subPackages = ReflectionUtil.getFieldValueOrNull(node, "subPackages");
if (subPackages != null) {
return new ArrayList<>(subPackages.values());
} else {
return null;
}
})
.setPredicate((theTree, theNode) -> {
if (!(theNode instanceof XClassHistogramRecord)) {
try {
java.lang.reflect.Field
field = theNode.getClass().getSuperclass().getDeclaredField("label");
field.setAccessible(true);
String labelName = (String) field.get(theNode);
return labelName.hashCode();
} catch (Throwable e) {
e.printStackTrace();
}
}
return null;
})
.findTargetParentNode(parentObjectId);
if (targetParentNode != null) {
Map<String, ?> packageMap = ReflectionUtil.getFieldValueOrNull(targetParentNode, "subPackages");
List<?> elems = new ArrayList<>();
if (packageMap != null) {
if (packageMap.size() == 0) {
elems = ReflectionUtil.getFieldValueOrNull(targetParentNode, "classes");
} else {
elems = new ArrayList<>(packageMap.values());
}
}
return
PageViewBuilder.<HistogramRecord, Model.Histogram.Item>fromList(
(List<HistogramRecord>) elems)
.paging(new PagingRequest(page, pageSize))
.map(e -> {
Model.Histogram.Item item = new Model.Histogram.Item();
String label = (String) pt.getColumnValue(e, 0);
item.setLabel(label);
if (e instanceof XClassHistogramRecord) {
int objectId = pt.getContext(e).getObjectId();
item.setObjectId(objectId);
item.setType(Model.Histogram.ItemType.CLASS);
} else {
item.setObjectId(label.hashCode());
item.setType(Model.Histogram.ItemType.PACKAGE);
}
if (label.matches("^int(\\[\\])*") || label.matches("^char(\\[\\])*") ||
label.matches("^byte(\\[\\])*") || label.matches("^short(\\[\\])*") ||
label.matches("^boolean(\\[\\])*") ||
label.matches("^double(\\[\\])*") ||
label.matches("^float(\\[\\])*") || label.matches("^long(\\[\\])*") ||
label.matches("^void(\\[\\])*")) {
item.setType(Model.Histogram.ItemType.CLASS);
}
item.setNumberOfObjects((Long) pt.getColumnValue(e, 1));
item.setShallowSize(((Bytes) pt.getColumnValue(e, 2)).getValue());
return item;
})
.sort(Model.Histogram.Item.sortBy(sortBy, ascendingOrder))
.done();
} else {
return PageView.empty();
}
}
default: {
throw new AnalysisException("Should not reach here");
}
}
});
}