< prev index next >
application/org.openjdk.jmc.flightrecorder.ui/src/main/java/org/openjdk/jmc/flightrecorder/ui/pages/MemoryLeakPage.java
Print this page
@@ -35,10 +35,11 @@
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.ToDoubleFunction;
import org.eclipse.jface.action.GroupMarker;
@@ -136,10 +137,28 @@
private static class ReferenceTreeContentProvider extends AbstractStructuredContentProvider
implements ITreeContentProvider {
IRange<IQuantity> timeRange = null;
+ private final Predicate<ReferenceTreeObject> withinTimeRangePredicateFromRootObject = rto -> {
+ if (timeRange != null) {
+ if (rto.getTimestamp().compareTo(timeRange.getStart()) >= 0
+ && rto.getTimestamp().compareTo(timeRange.getEnd()) <= 0) {
+ return true;
+ } else if (rto.getRootObject().getLeafNodes() != null && rto.getRootObject().getLeafNodes().size() > 1) {
+ for (Map.Entry<IQuantity, ReferenceTreeObject> rt : rto.getRootObject().getLeafNodes().entrySet()) {
+ if (rt.getKey().compareTo(timeRange.getStart()) >= 0
+ && rt.getKey().compareTo(timeRange.getEnd()) <= 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ return true;
+ };
+
private final Predicate<ReferenceTreeObject> withinTimeRangePredicate = rto -> {
if (timeRange != null) {
return rto.getTimestamp().compareTo(timeRange.getStart()) >= 0
&& rto.getTimestamp().compareTo(timeRange.getEnd()) <= 0;
}
@@ -158,11 +177,11 @@
public boolean hasChildren(Object element) {
if (element instanceof ReferenceTreeObject) {
ReferenceTreeObject object = (ReferenceTreeObject) element;
List<ReferenceTreeObject> children = object.getChildren();
if (timeRange != null) {
- return children.stream().anyMatch(withinTimeRangePredicate);
+ return children.stream().anyMatch(withinTimeRangePredicateFromRootObject);
}
return !children.isEmpty();
}
return false;
}
@@ -179,11 +198,11 @@
@Override
public Object[] getElements(Object inputElement) {
if (inputElement instanceof Collection<?>) {
Collection<ReferenceTreeObject> collection = (Collection<ReferenceTreeObject>) inputElement;
if (timeRange != null) {
- return collection.stream().filter(withinTimeRangePredicate).toArray();
+ return collection.stream().filter(withinTimeRangePredicateFromRootObject).toArray();
}
return collection.toArray();
}
return new Object[0];
}
@@ -192,11 +211,16 @@
public Object[] getChildren(Object element) {
if (element instanceof ReferenceTreeObject) {
ReferenceTreeObject object = (ReferenceTreeObject) element;
List<ReferenceTreeObject> children = object.getChildren();
if (timeRange != null) {
+ // Node has more than 1 children, select only those nodes which are leaky (leaf node) objects
+ if (children.size() > 1) {
return children.stream().filter(withinTimeRangePredicate).toArray();
+ } else {
+ return children.stream().filter(withinTimeRangePredicateFromRootObject).toArray();
+ }
}
return children.toArray();
}
return new Object[0];
}
@@ -246,11 +270,16 @@
}).build();
private final IColumn COUNT_COLUMN = new ColumnBuilder(Messages.MemoryLeakPage_COUNT_COLUMN_HEADER, "count", //$NON-NLS-1$
new TypedLabelProvider<ReferenceTreeObject>(ReferenceTreeObject.class) {
@Override
protected String getTextTyped(ReferenceTreeObject object) {
- return object == null ? "" : Integer.toString(object.getItems().size()); //$NON-NLS-1$
+ IRange<IQuantity> selectionRange = chart.getSelectionRange();
+ if (selectionRange == null) {
+ return object == null ? "" : Integer.toString(object.getObjectsKeptAliveCount()); //$NON-NLS-1$
+ } else {
+ return (object == null || selectionRange == null) ? "" : Integer.toString(model.getLeakCountInRange(selectionRange, object)); //$NON-NLS-1$
+ }
};
}).style(SWT.RIGHT).comparator((o1, o2) -> {
if (o1 instanceof ReferenceTreeObject && o2 instanceof ReferenceTreeObject) {
return ((ReferenceTreeObject) o1).getObjectsKeptAliveCount()
- ((ReferenceTreeObject) o2).getObjectsKeptAliveCount();
@@ -308,11 +337,11 @@
TableSettings.forState(state.getChild(REFERENCE_TREE)));
configureColumnManager(editor, referenceTree, null, Messages.MemoryLeakPage_OBJECT_SAMPLES_SELECTION,
state.getChild(REFERENCE_TREE), null);
model = ReferenceTreeModel.buildReferenceTree(getDataSource().getItems().apply(TABLE_ITEMS));
model.getLeakCandidates(0.5d); // this doesn't really matter, since we're not saving the return value
- aggregatedReferenceTree.setInput(model.getRootObjects());
+ aggregatedReferenceTree.setInput(model.getLeakObjects());
chartCanvas.replaceRenderer(createChart());
PersistableSashForm.loadState(mainSash, state.getChild(MAIN_SASH));
}
@@ -377,11 +406,11 @@
if (aggregatedReferenceTree != null && model != null) {
IRange<IQuantity> selectionRange = chart.getSelectionRange();
if (selectionRange != null) {
((ReferenceTreeContentProvider) aggregatedReferenceTree
.getContentProvider()).timeRange = selectionRange;
- aggregatedReferenceTree.setInput(model.getRootObjects(selectionRange));
+ aggregatedReferenceTree.setInput(model.getLeakObjects(selectionRange));
} else {
((ReferenceTreeContentProvider) aggregatedReferenceTree.getContentProvider()).timeRange = null;
aggregatedReferenceTree.setInput(model.getRootObjects());
}
}
< prev index next >