Java遍历对象可访问的对象(堆1.0)
本文向大家介绍Java遍历对象可访问的对象(堆1.0),包括了Java遍历对象可访问的对象(堆1.0)的使用技巧和注意事项,需要的朋友参考一下
示例
#include <vector> #include <string> #include "agent_util.hpp" //该文件可以在Java SE Development Kit 8u101演示和样本中找到。 //see http://download.oracle.com/otn-pub/java/jdk/8u101-b13-demos/jdk-8u101-windows-x64-demos.zip //jdk1.8.0_101.zip!\demo\jvmti\versionCheck\src\agent_util.h /* * Struct used for jvmti->SetTag(object, <pointer to tag>); * http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#SetTag * */ typedef struct Tag { jlong referrer_tag; jlong size; char* classSignature; jint hashCode; } Tag; /* * Utility function: jlong -> Tag* */ static Tag* pointerToTag(jlong tag_ptr) { if (tag_ptr == 0) { return new Tag(); } return (Tag*)(ptrdiff_t)(void*)tag_ptr; } /* * Utility function: Tag* -> jlong */ static jlong tagToPointer(Tag* tag) { return (jlong)(ptrdiff_t)(void*)tag; } /* * Heap 1.0 Callback * http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#jvmtiObjectReferenceCallback */ static jvmtiIterationControl JNICALL heabObjectReferencesCallback( jvmtiObjectReferenceKind reference_kind, jlong class_tag, jlong size, jlong* tag_ptr, jlong referrer_tag, jint referrer_index, void* user_data) { //仅在参考字段上迭代 if (reference_kind != JVMTI_HEAP_REFERENCE_FIELD) { return JVMTI_ITERATION_IGNORE; } auto tag_ptr_list = (std::vector<jlong>*)(ptrdiff_t)(void*)user_data; //创建并分配标签 auto t = pointerToTag(*tag_ptr); t->referrer_tag = referrer_tag; t->size = size; *tag_ptr = tagToPointer(t); //收集标签 (*tag_ptr_list).push_back(*tag_ptr); return JVMTI_ITERATION_CONTINUE; } /* * Main function for demonstration of Iterate Over Objects Reachable From Object * http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#IterateOverObjectsReachableFromObject * */ void iterateOverObjectHeapReferences(jvmtiEnv* jvmti, JNIEnv* env, jobject object) { std::vector<jlong> tag_ptr_list; auto t = new Tag(); jvmti->SetTag(object, tagToPointer(t)); tag_ptr_list.push_back(tagToPointer(t)); stdout_message("tag list size before call callback: %d\n", tag_ptr_list.size()); /* * Call Callback for every reachable object reference * see http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#IterateOverObjectsReachableFromObject */ jvmti->IterateOverObjectsReachableFromObject(object, &heabObjectReferencesCallback, (void*)&tag_ptr_list); stdout_message("tag list size after call callback: %d\n", tag_ptr_list.size()); if (tag_ptr_list.size() > 0) { jint found_count = 0; jlong* tags = &tag_ptr_list[0]; jobject* found_objects; jlong* found_tags; /* * collect all tagged object (via *tag_ptr = pointer to tag ) * see http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#GetObjectsWithTags */ jvmti->GetObjectsWithTags(tag_ptr_list.size(), tags, &found_count, &found_objects, &found_tags); stdout_message("found %d objects\n", found_count); for (auto i = 0; i < found_count; ++i) { jobject found_object = found_objects[i]; char* classSignature; jclass found_object_class = env->GetObjectClass(found_object); /* * Get string representation of found_object_class * see http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#GetClassSignature */ jvmti->GetClassSignature(found_object_class, &classSignature, nullptr); jint hashCode; /* * Getting hash code for found_object * see http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#GetObjectHashCode */ jvmti->GetObjectHashCode(found_object, &hashCode); //将其全部保存在标签中 Tag* t = pointerToTag(found_tags[i]); t->classSignature = classSignature; t->hashCode = hashCode; } //打印所有保存的信息 for (auto i = 0; i < found_count; ++i) { auto t = pointerToTag(found_tags[i]); auto rt = pointerToTag(t->referrer_tag); if (t->referrer_tag != 0) { stdout_message("referrer object %s#%d --> object %s#%d (size: %2d)\n", rt->classSignature, rt->hashCode, t->classSignature, t->hashCode, t->size); } } } }