in src/sizes/retained_size_via_dominator_tree.cpp [214:251]
jobjectArray RetainedSizesByClassViaDominatorTreeAction::executeOperation(jobject classRef, jlong objectsLimit) {
jvmtiError err = jvmti->SetTag(classRef, CLASS_TAG);
if (!isOk(err)) return nullptr;
progressManager.updateProgress(5, "Collecting objects of class");
err = FollowReferences(0, nullptr, nullptr, collectObjects, nullptr);
if (!isOk(err) || shouldStopExecution()) return nullptr;
std::vector<jobject> objectsOfClass;
err = getObjectsByTags(jvmti, std::vector<jlong>{OBJECT_OF_CLASS_TAG}, objectsOfClass);
if (!isOk(err) || shouldStopExecution()) return nullptr;
// Constructing the master node
jobjectArray objects = getObjectArrayOfSize(env, objectsOfClass.size());
for (int i = 0; i < objectsOfClass.size(); i++) {
env->SetObjectArrayElement(objects, i, objectsOfClass[i]);
}
err = jvmti->SetTag(classRef, 0);
if (!isOk(err)) return nullptr;
SizesViaDominatorTreeHeapDumpInfo info;
std::vector<jlong> retainedSizes;
err = calculateRetainedSizes(objects, retainedSizes, info);
if (!isOk(err) || shouldStopExecution()) return nullptr;
// Sort objects by their retained size
std::sort(objectsOfClass.begin(), objectsOfClass.end(), [&](jobject a, jobject b) {
jlong tagA;
jvmti->GetTag(a, &tagA);
jlong tagB;
jvmti->GetTag(b, &tagB);
return retainedSizes[tagA] > retainedSizes[tagB];
});
progressManager.updateProgress(95, "Extracting answer...");
return constructResultObject(objectsOfClass, retainedSizes, info, objectsLimit);
}