// Copyright (C) 2018 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //
// Special art ti-version number. We will use this as a fallback if we cannot get a regular JVMTI // env. static constexpr jint kArtTiVersion = JVMTI_VERSION_1_2 | 0x40000000;
staticvoid DataDumpRequestCb(jvmtiEnv* jvmti) {
JNIEnv* env = nullptr;
CHECK_EQ(java_vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6), JNI_OK);
LOG(INFO) << "Dumping counts of fields.";
LOG(INFO) << "\t" << "Field name"
<< "\t" << "Type"
<< "\t" << "Count"
<< "\t" << "TotalSize";
RequestList* list;
CHECK_JVMTI(jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&list))); for (std::pair<jclass, jfieldID>& p : list->fields_) {
jclass klass = p.first;
jfieldID field = p.second; // Make sure all instances of the class are tagged with the klass ptr value. Since this is a // global ref it's guaranteed to be unique.
CHECK_JVMTI(jvmti->IterateOverInstancesOfClass(
p.first, // We need to do this to all objects every time since we might be looking for multiple // fields in classes that are subtypes of each other.
JVMTI_HEAP_OBJECT_EITHER, /* class_tag, size, tag_ptr, user_data*/
[](jlong, jlong, jlong* tag_ptr, void* klass) -> jvmtiIterationControl {
*tag_ptr = static_cast<jlong>(reinterpret_cast<intptr_t>(klass)); return JVMTI_ITERATION_CONTINUE;
},
klass));
jobject* obj_list;
jint obj_len;
jlong tag = static_cast<jlong>(reinterpret_cast<intptr_t>(klass));
CHECK_JVMTI(jvmti->GetObjectsWithTags(1, &tag, &obj_len, &obj_list, nullptr));
std::unordered_map<std::string, size_t> class_sizes;
std::unordered_map<std::string, size_t> class_counts;
size_t total_size = 0; // Mark all the referenced objects with a single tag value, this way we can dedup them.
jlong referenced_object_tag = static_cast<jlong>(reinterpret_cast<intptr_t>(klass) + 1);
std::string null_class_name("<null>");
class_counts[null_class_name] = 0;
class_sizes[null_class_name] = 0; for (jint i = 0; i < obj_len; i++) {
ScopedLocalRef<jobject> cur_thiz(env, obj_list[i]);
ScopedLocalRef<jobject> obj(env, env->GetObjectField(cur_thiz.get(), field));
std::string class_name(null_class_name); if (obj == nullptr) {
class_counts[null_class_name]++;
} else {
CHECK_JVMTI(jvmti->SetTag(obj.get(), referenced_object_tag));
jlong size = 0; if (obj.get() != nullptr) { char* class_name_tmp;
ScopedLocalRef<jclass> obj_klass(env, env->GetObjectClass(obj.get()));
CHECK_JVMTI(jvmti->GetClassSignature(obj_klass.get(), &class_name_tmp, nullptr));
CHECK_JVMTI(jvmti->GetObjectSize(obj.get(), &size));
class_name = class_name_tmp;
CHECK_JVMTI(jvmti->Deallocate(reinterpret_cast<unsignedchar*>(class_name_tmp)));
} if (class_sizes.find(class_name) == class_counts.end()) {
class_sizes[class_name] = 0;
class_counts[class_name] = 0;
}
class_counts[class_name]++;
}
}
jobject* ref_list;
jint ref_len;
CHECK_JVMTI(jvmti->GetObjectsWithTags(1, &referenced_object_tag, &ref_len, &ref_list, nullptr)); for (jint i = 0; i < ref_len; i++) {
ScopedLocalRef<jobject> obj(env, ref_list[i]);
std::string class_name(null_class_name);
jlong size = 0; if (obj.get() != nullptr) { char* class_name_tmp;
ScopedLocalRef<jclass> obj_klass(env, env->GetObjectClass(obj.get()));
CHECK_JVMTI(jvmti->GetClassSignature(obj_klass.get(), &class_name_tmp, nullptr));
CHECK_JVMTI(jvmti->GetObjectSize(obj.get(), &size));
class_name = class_name_tmp;
CHECK_JVMTI(jvmti->Deallocate(reinterpret_cast<unsignedchar*>(class_name_tmp)));
}
total_size += static_cast<size_t>(size);
class_sizes[class_name] += static_cast<size_t>(size);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.