-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Retained size by ClassLoaders #35
base: master
Are you sure you want to change the base?
Changes from all commits
9cdbad5
6ce9b73
ebbd561
c15a6af
881e5b6
3338af1
a33d6b0
17a208e
a99104a
000ef33
29289a0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. | ||
|
||
#include <vector> | ||
#include "retained_size_by_classloaders.h" | ||
#include <algorithm> | ||
#include <numeric> | ||
|
||
|
||
jvmtiError RetainedSizeByClassLoadersAction::tagObjectsByClassLoader(jclass *classes, jint* cnt, jobject classLoader, jsize classLoaderIndex) { | ||
jvmtiError err = JVMTI_ERROR_NONE; | ||
std::vector<jclass> filteredClasses; | ||
for (jsize i = 0; i < *cnt; i++) { | ||
jobject rootClassLoader = getClassLoader(env, classes[i]); | ||
if (!env->IsSameObject(rootClassLoader, NULL)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here we can combine these conditions:
|
||
if (isEqual(env, classLoader, rootClassLoader)) { | ||
filteredClasses.emplace_back(classes[i]); | ||
} | ||
} | ||
} | ||
|
||
err = tagObjectsOfClassLoaderClasses(toJavaArray(env, filteredClasses), classLoaderIndex); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets rewrite it like this:
|
||
if (!isOk(err)) return err; | ||
if (shouldStopExecution()) return MEMORY_AGENT_INTERRUPTED_ERROR; | ||
return err; | ||
} | ||
|
||
jvmtiError RetainedSizeByClassLoadersAction::tagObjectsByClassLoaderSimple(jclass *classes, jint* cnt, jobject classLoader) { | ||
jvmtiError err = JVMTI_ERROR_NONE; | ||
std::vector<jclass> filteredClasses; | ||
for (jsize i = 0; i < *cnt; i++) { | ||
jobject rootClassLoader = getClassLoader(env, classes[i]); | ||
if (!env->IsSameObject(rootClassLoader, NULL)) { | ||
if (isEqual(env, classLoader, rootClassLoader)) { | ||
filteredClasses.emplace_back(classes[i]); | ||
} | ||
} | ||
} | ||
|
||
debug("tag objects of classes"); | ||
err = createTagsForClassLoadersClassesSimple(this->env, this->jvmti, toJavaArray(env, filteredClasses)); | ||
if (err != JVMTI_ERROR_NONE) return err; | ||
|
||
err = this->IterateThroughHeap(0, nullptr, tagObjectOfTaggedClassSimple, nullptr); | ||
if (!isOk(err)) return err; | ||
if (shouldStopExecution()) return MEMORY_AGENT_INTERRUPTED_ERROR; | ||
return err; | ||
} | ||
|
||
jlong RetainedSizeByClassLoadersAction::tagOtherObjects(jclass *classes, jint* cnt, jobjectArray classLoadersArray) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this function should return |
||
jvmtiError err = JVMTI_ERROR_NONE; | ||
std::vector<jclass> filteredClasses; | ||
for (jsize i = 0; i < *cnt; i++) { | ||
jobject rootClassLoader = getClassLoader(env, classes[i]); | ||
if (!env->IsSameObject(rootClassLoader, NULL)) { | ||
for (jsize j = 0; j < env->GetArrayLength(classLoadersArray); j++) { | ||
if (isEqual(env, env->GetObjectArrayElement(classLoadersArray, j), rootClassLoader)) { | ||
filteredClasses.emplace_back(classes[i]); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
std::vector<jclass> nonfilteredClasses; | ||
for (jsize i = 0; i < *cnt; i++) { | ||
if (std::find(filteredClasses.begin(), filteredClasses.end(), classes[i]) == filteredClasses.end()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be much better to store filtered classes in |
||
nonfilteredClasses.emplace_back(classes[i]); | ||
} | ||
} | ||
std::cout << "SIZE: " << nonfilteredClasses.size() << std::endl; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use the logger instead |
||
|
||
err = tagObjectsOfClassLoaderClasses(toJavaArray(env, nonfilteredClasses), env->GetArrayLength(classLoadersArray)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
|
||
jlong RetainedSizeByClassLoadersAction::getHeapSize(){ | ||
jlong totalSize = 0; | ||
IterateThroughHeap(0, nullptr, countHeapSize, &totalSize, | ||
"calculate heap size"); | ||
return totalSize; | ||
} | ||
|
||
RetainedSizeByClassLoadersAction::RetainedSizeByClassLoadersAction(JNIEnv *env, jvmtiEnv *jvmti, jobject object) | ||
: RetainedSizeAction(env, jvmti, object), retainedSizeByObjectsMergedAction(env, jvmti, object), retainedSizeByObjectsAction(env, jvmti, object) { | ||
|
||
} | ||
|
||
jvmtiError RetainedSizeByClassLoadersAction::getRetainedSizeByClassLoaders(jobjectArray classLoadersArray, | ||
std::vector <jlong> &result) { | ||
jvmtiError err = JVMTI_ERROR_NONE; | ||
jclass *classes; | ||
jint cnt; | ||
err = jvmti->GetLoadedClasses(&cnt, &classes); | ||
for (jsize i = 0; i < env->GetArrayLength(classLoadersArray); i++) { | ||
jvmtiError err = tagObjectsByClassLoader(classes, &cnt, env->GetObjectArrayElement(classLoadersArray, i), i); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also there's no need to declare a new variable here |
||
} | ||
tagOtherObjects(classes, &cnt, classLoadersArray); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
if (!isOk(err)) return err; | ||
if (shouldStopExecution()) return MEMORY_AGENT_INTERRUPTED_ERROR; | ||
|
||
err = tagHeap(); | ||
if (!isOk(err)) return err; | ||
if (shouldStopExecution()) return MEMORY_AGENT_INTERRUPTED_ERROR; | ||
|
||
result.resize(env->GetArrayLength(classLoadersArray) + 1); | ||
err = IterateThroughHeap(JVMTI_HEAP_FILTER_UNTAGGED, nullptr, visitObject, result.data(), | ||
"calculate retained size"); | ||
return err; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
|
||
jvmtiError RetainedSizeByClassLoadersAction::getRetainedSizeByClassLoaderSimple(jobject classLoader, | ||
jlong* result) { | ||
jvmtiError err = JVMTI_ERROR_NONE; | ||
jclass *classes; | ||
jint cnt; | ||
err = jvmti->GetLoadedClasses(&cnt, &classes); | ||
err = tagObjectsByClassLoaderSimple(classes, &cnt, classLoader); | ||
std::cout << "tagged" << std::endl; | ||
|
||
if (!isOk(err)) return err; | ||
if (shouldStopExecution()) return MEMORY_AGENT_INTERRUPTED_ERROR; | ||
|
||
std::vector<jobject> objects; | ||
err = getObjectsByTags(this->jvmti, std::vector<jlong>{13}, objects); | ||
std::cout << "get objects" << std::endl; | ||
if (err != JVMTI_ERROR_NONE) return err; | ||
if (this->shouldStopExecution()) return MEMORY_AGENT_INTERRUPTED_ERROR; | ||
removeAllTagsFromHeap(jvmti, nullptr); | ||
|
||
std::cout << "remove tags" << std::endl; | ||
std::cout << objects.size() << std::endl; | ||
auto r = retainedSizeByObjectsMergedAction.run(toJavaArray(env, objects)); | ||
result = reinterpret_cast<jlong*>(env->GetObjectArrayElement(r, 0)); | ||
std::cout << result << " " << *result << std::endl; | ||
removeAllTagsFromHeap(jvmti, nullptr); | ||
return err; | ||
} | ||
|
||
jlongArray RetainedSizeByClassLoadersAction::executeOperation(jobjectArray classLoadersArray) { | ||
std::vector <jlong> result; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An extra space |
||
jvmtiError err = getRetainedSizeByClassLoaders(classLoadersArray, result); | ||
std::cout << "CLASSLOADERS CLASSES: " << result[0] <<std::endl; | ||
std::vector <jlong> otherRes; | ||
for (jsize i = 0; i < env->GetArrayLength(classLoadersArray); i++) { | ||
jlong res; | ||
jvmtiError err = getRetainedSizeByClassLoaderSimple(env->GetObjectArrayElement(classLoadersArray, i), &res); | ||
otherRes.push_back(res); | ||
} | ||
if (!isOk(err)) { | ||
handleError(jvmti, err, "Could not estimate retained size by classLoaders"); | ||
return env->NewLongArray(0); | ||
} | ||
//std::cout << "HEAP SIZE: " << getHeapSize() << std::endl; | ||
std::cout << "CLASSLOADERS CLASSES CHECK: " << std::accumulate(otherRes.begin(), otherRes.end(), 0l) <<std::endl; | ||
std::cout << "OTHER CLASSES: " << result.back() <<std::endl; | ||
result.pop_back(); | ||
return toJavaArray(env, result); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. | ||
|
||
#ifndef MEMORY_AGENT_RETAINED_SIZE_BY_CLASSLOADERS_H | ||
#define MEMORY_AGENT_RETAINED_SIZE_BY_CLASSLOADERS_H | ||
|
||
#include "../memory_agent_action.h" | ||
#include "retained_size_action.h" | ||
#include "retained_size_by_objects_merged.h" | ||
#include "retained_size_by_objects.h" | ||
#include "retained_size_by_classes.h" | ||
|
||
|
||
class RetainedSizeByClassLoadersAction : public RetainedSizeAction<jlongArray> { | ||
public: | ||
RetainedSizeByClassLoadersAction(JNIEnv *env, jvmtiEnv *jvmti, jobject object); | ||
RetainedSizeByObjectsMergedAction retainedSizeByObjectsMergedAction; | ||
RetainedSizeByObjectsAction retainedSizeByObjectsAction; | ||
|
||
private: | ||
jlongArray executeOperation(jobjectArray classLoadersArray) override; | ||
jvmtiError getRetainedSizeByClassLoaders(jobjectArray classLoadersArray, std::vector<jlong> &result); | ||
jvmtiError getRetainedSizeByClassLoaderSimple(jobject classLoader, jlong* result); | ||
jvmtiError tagObjectsByClassLoader(jclass *classes, jint* cnt, jobject classLoader, jsize classLoaderIndex); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Asterisks should stick to the variable name |
||
jvmtiError tagObjectsByClassLoaderSimple(jclass *classes, jint* cnt, jobject classLoader); | ||
jlong getHeapSize(); | ||
jlong tagOtherObjects(jclass *classes, jint* cnt, jobjectArray classLoadersArray); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Asterisks should stick to the variable name |
||
}; | ||
|
||
jint JNICALL visitObject(jlong classTag, jlong size, jlong *tagPtr, jint length, void *userData); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this function should not be declared here |
||
|
||
|
||
|
||
#endif //MEMORY_AGENT_RETAINED_SIZE_BY_CLASSLOADERS_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Asterisks should stick to the variable name