[515399] Use BitField not SetInt for ComponentReportQuery
retained list of objects could be huge, so use a BitField in that case
rather than SetInt to avoid memory and capacity problems
Change-Id: Ic11676bcad1508b2a0c63bcae7c3c3ff05d0fef3
diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/component/ComponentReportQuery.java b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/component/ComponentReportQuery.java
index 7b93ceb..da413d2 100644
--- a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/component/ComponentReportQuery.java
+++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/component/ComponentReportQuery.java
@@ -22,6 +22,7 @@
import org.eclipse.mat.SnapshotException;
import org.eclipse.mat.collect.ArrayInt;
+import org.eclipse.mat.collect.BitField;
import org.eclipse.mat.collect.SetInt;
import org.eclipse.mat.inspections.InspectionAssert;
import org.eclipse.mat.inspections.ReferenceQuery;
@@ -845,10 +846,26 @@
return;
}
- // SetInt will resize when it is 75% full, so allocate it big enough now
- SetInt retainedSet = new SetInt(Math.max(((retained.length + 2) / 3) * 4, retained.length));
+ // Currently SetInt uses a lot of memory - 32+8 bits @ 75% capacity = 53 bits per item
+ boolean useBits = retained.length > Math.max(100000, snapshot.getSnapshotInfo().getNumberOfObjects() / 53);
+ SetInt retainedSet = null;
+ BitField retainedIds = null;
+ if (useBits)
+ {
+ retainedIds = new BitField(snapshot.getSnapshotInfo().getNumberOfObjects());
+ }
+ else
+ {
+ // SetInt will resize when it is 75% full, so allocate it big enough now
+ retainedSet = new SetInt(Math.max(((retained.length + 2) / 3) * 4, retained.length));
+ }
for (int ii = 0; ii < retained.length; ii++)
- retainedSet.add(retained[ii]);
+ {
+ if (useBits)
+ retainedIds.set(retained[ii]);
+ else
+ retainedSet.add(retained[ii]);
+ }
// Avoid duplicates from the two approaches by using a set
SetInt finalizers = new SetInt();
@@ -863,7 +880,7 @@
if (ref != null)
{
int referentId = ref.getObjectId();
- if (retainedSet.contains(referentId))
+ if (useBits ? retainedIds.get(referentId) : retainedSet.contains(referentId))
{
finalizers.add(referentId);
}
@@ -881,7 +898,7 @@
|| rootInfo.getType() == GCRootInfo.Type.FINALIZABLE)
{
int referentId = rootInfo.getObjectId();
- if (retainedSet.contains(referentId))
+ if (useBits ? retainedIds.get(referentId) : retainedSet.contains(referentId))
{
finalizers.add(referentId);
}