hprof_heapdump.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 943 行 · 第 1/2 页
C
943 行
/* * @(#)hprof_heapdump.c 1.17 06/10/10 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */#include "javavm/include/porting/ansi/string.h"#include "jvmpi.h"#include "hprof.h"void hprof_get_heap_dump(void) { if (CALL(RequestEvent)(JVMPI_EVENT_HEAP_DUMP, NULL) != JVMPI_SUCCESS) { fprintf(stderr, "HPROF ERROR: heap dump from JVM did not succeed\n"); }}#ifdef HPROF_HEAPDUMP_DEBUGstatic voidhprof_print_tag(int tag){ char *t; switch(tag){ case HPROF_GC_ROOT_MONITOR_USED: t = "busy monitor"; break; case HPROF_GC_ROOT_STICKY_CLASS: t = "sticky class"; break; case HPROF_GC_ROOT_UNKNOWN: t = "unknown root"; break; case HPROF_GC_ROOT_JNI_GLOBAL: t = "jni global"; break; case HPROF_GC_ROOT_THREAD_BLOCK: t = "thread block"; break; case HPROF_GC_ROOT_NATIVE_STACK: t = "native stack"; break; case HPROF_GC_ROOT_JAVA_FRAME: t = "java frame"; break; case HPROF_GC_ROOT_JNI_LOCAL: t = "jni local"; break; case HPROF_GC_CLASS_DUMP: t = "class object"; break; case HPROF_GC_INSTANCE_DUMP: t = "instance"; break; case HPROF_GC_OBJ_ARRAY_DUMP: t = "array of object"; break; case HPROF_GC_PRIM_ARRAY_DUMP: t = "array of scalar"; break; default: t = "GARBAGE"; break; } fprintf(stderr,"Heap dump object %s\n", t);}#endif /* HPROF_HEAPDUMP_DEBUG *//* this function is used to get the size of the heap dump record output by hprof if the output format is binary */static int hprof_get_dump_size(char *begin_roots, char *end_objects){ int size = 0; hprof_dump_seek(begin_roots); while (hprof_dump_cur() < end_objects) { unsigned char tag; int in; int out; int sizeof_u1 = sizeof(unsigned char); int sizeof_u2 = sizeof(unsigned short); int sizeof_u4 = sizeof(unsigned int); int sizeof_id = sizeof(void *); tag = hprof_dump_read_u1(); size += sizeof_u1;#ifdef HPROF_HEAPDUMP_DEBUG hprof_print_tag(tag);#endif /* HPROF_HEAPDUMP_DEBUG */ switch (tag) { case HPROF_GC_ROOT_MONITOR_USED: case HPROF_GC_ROOT_STICKY_CLASS: case HPROF_GC_ROOT_UNKNOWN: { in = sizeof_id; out = sizeof_id; size += out; hprof_dump_seek(hprof_dump_cur() + in); break; } case HPROF_GC_ROOT_JNI_GLOBAL: { in = 2 * sizeof_id; out = 2 * sizeof_id; size += out; hprof_dump_seek(hprof_dump_cur() + in); break; } case HPROF_GC_ROOT_THREAD_BLOCK: case HPROF_GC_ROOT_NATIVE_STACK: { in = 2 * sizeof_id; out = sizeof_id + sizeof_u4; size += out; hprof_dump_seek(hprof_dump_cur() + in); break; } case HPROF_GC_ROOT_JAVA_FRAME: case HPROF_GC_ROOT_JNI_LOCAL: { in = 2 * sizeof_id + sizeof_u4; out = sizeof_id + 2 * sizeof_u4; size += out; hprof_dump_seek(hprof_dump_cur() + in); break; } case HPROF_GC_CLASS_DUMP: { int n; int i; jobjectID class_id = hprof_dump_read_id(); hprof_class_t *class = hprof_lookup_class(class_id); if (class == NULL) { fprintf(stderr, "HPROF ERROR: unknown class_id in get_dump_size %p\n", class_id); return -1; } in = 6 * sizeof_id + sizeof_u4; out = 7 * sizeof_id + 2 * sizeof_u4; size += out; hprof_dump_seek(hprof_dump_cur() + in); in = class->num_interfaces * sizeof_id; hprof_dump_seek(hprof_dump_cur() + in); n = hprof_dump_read_u2(); size += sizeof_u2; in = n*(sizeof_u2 + sizeof_u1 + sizeof_id); out = in; size += out; hprof_dump_seek(hprof_dump_cur() + in); n = class->num_statics; size += sizeof_u2; for (i = 0; i < n; i++) { jint ty = class->statics[i].type; size += sizeof_id + sizeof_u1; if (ty == JVMPI_LONG || ty == JVMPI_DOUBLE) { in = sizeof(jvalue); out = in; size += out; hprof_dump_seek(hprof_dump_cur() + in); } else if (ty == JVMPI_CLASS) { in = sizeof_id; out = sizeof_id; size += out; hprof_dump_seek(hprof_dump_cur() + in); } else if (ty == JVMPI_INT || ty == JVMPI_FLOAT) { in = sizeof_u4; out = sizeof_u4; size += out; hprof_dump_seek(hprof_dump_cur() + in); } else if (ty == JVMPI_CHAR || ty == JVMPI_SHORT) { in = sizeof_u2; out = sizeof_u2; size += out; hprof_dump_seek(hprof_dump_cur() + in); } else if (ty == JVMPI_BYTE || ty == JVMPI_BOOLEAN) { in = sizeof_u1; out = sizeof_u1; size += out; hprof_dump_seek(hprof_dump_cur() + in); } } size += sizeof_u2 + class->num_instances*(sizeof_id + sizeof_u1); break; } case HPROF_GC_INSTANCE_DUMP: { unsigned int valbytes; in = 2 * sizeof_id; out = 2 * sizeof_id + sizeof_u4; size += out; hprof_dump_seek(hprof_dump_cur() + in); valbytes = hprof_dump_read_u4(); size += sizeof_u4; size += valbytes; hprof_dump_seek(hprof_dump_cur() + valbytes); break; } case HPROF_GC_OBJ_ARRAY_DUMP: { unsigned int num_elements; in = sizeof_id; out = sizeof_id + sizeof_u4; size += out; hprof_dump_seek(hprof_dump_cur() + in); num_elements = hprof_dump_read_u4(); size += sizeof_u4; in = sizeof_id + num_elements * sizeof_id; out = in; size += out; hprof_dump_seek(hprof_dump_cur() + in); break; } case HPROF_GC_PRIM_ARRAY_DUMP: { unsigned int num_elements; unsigned char ty; in = sizeof_id; out = sizeof_id + sizeof_u4; size += out; hprof_dump_seek(hprof_dump_cur() + in); num_elements = hprof_dump_read_u4(); size += sizeof_u4; ty = hprof_dump_read_u1(); size += sizeof_u1; switch (ty) { case JVMPI_BYTE: case JVMPI_BOOLEAN: in = num_elements * sizeof_u1; out = in; size += out; hprof_dump_seek(hprof_dump_cur() + in); break; case JVMPI_SHORT: case JVMPI_CHAR: in = num_elements * sizeof_u2; out = in; size += out; hprof_dump_seek(hprof_dump_cur() + in); break; case JVMPI_FLOAT: case JVMPI_INT: in = num_elements * sizeof_u4; out = in; size += out; hprof_dump_seek(hprof_dump_cur() + in); break; case JVMPI_DOUBLE: case JVMPI_LONG: in = num_elements * 2 * sizeof_u4; out = in; size += out; hprof_dump_seek(hprof_dump_cur() + in); break; } break; } } } return size;}/* this function processes the heap dump buffer and outputs the second part of the heap dump record */static void hprof_process_dump_buffer(char *begin_roots, char *end_objects){ int i; hprof_dump_seek(begin_roots); while (hprof_dump_cur() < end_objects) { unsigned char tag; tag = hprof_dump_read_u1(); if (output_format == 'b') { hprof_write_u1(tag); } switch (tag) { case HPROF_GC_ROOT_UNKNOWN: { void *obj_id = hprof_dump_read_id(); hprof_objmap_t *objmap = hprof_fetch_object_info(obj_id); if (output_format == 'b') { hprof_write_id(objmap); } else { hprof_printf("ROOT %x (kind=<unknown>)\n", objmap); } break; } case HPROF_GC_ROOT_JNI_GLOBAL: { void *obj_id; void *ref_id; hprof_globalref_t *gref; unsigned int trace_serial_num; hprof_dump_read_id(); /* skip object id, we can get it from gref */ ref_id = hprof_dump_read_id(); gref = hprof_globalref_find(ref_id); if (gref == NULL) { obj_id = NULL; trace_serial_num = 0; } else { obj_id = gref->obj_id; /* already objmapped */ trace_serial_num = gref->trace_serial_num; } if (output_format == 'b') { hprof_write_id(obj_id); hprof_write_id(ref_id); } else { hprof_printf("ROOT %x (kind=<JNI global ref>, " "id=%x, trace=%u)\n", obj_id, ref_id, trace_serial_num); } break; } case HPROF_GC_ROOT_NATIVE_STACK: { void *h = hprof_dump_read_id(); hprof_objmap_t *objmap = hprof_fetch_object_info(h); void *env = hprof_dump_read_id(); hprof_thread_t *thread = hprof_lookup_thread(env); unsigned int thread_serial_num; void *tid; if (thread == NULL) { thread_serial_num = 0; tid = NULL; } else { thread_serial_num = thread->serial_num; tid = thread->thread_id; /* already objmapped */ } if (output_format == 'b') { hprof_write_id(objmap); hprof_write_u4(thread_serial_num); } else { hprof_printf("ROOT %x (kind=<native stack>, thread=%u)\n", objmap, thread_serial_num, tid); } break; } case HPROF_GC_ROOT_STICKY_CLASS: { void *class_id = hprof_dump_read_id(); hprof_objmap_t *objmap = hprof_fetch_object_info(class_id); if (output_format == 'b') { hprof_write_id(objmap); } else { hprof_class_t *class = hprof_lookup_class_objmap(objmap); const char *class_name = (class == NULL) ? "<Unknown>" : class->name->name; hprof_printf("ROOT %x (kind=<system class>, name=%s)\n", objmap, class_name); } break; } case HPROF_GC_ROOT_THREAD_BLOCK: { void *h = hprof_dump_read_id(); hprof_objmap_t *objmap = hprof_fetch_object_info(h); void *env = hprof_dump_read_id(); hprof_thread_t *thread = hprof_lookup_thread(env); unsigned int thread_serial_num = (thread == NULL) ? 0 : thread->serial_num; if (output_format == 'b') { hprof_write_id(objmap); hprof_write_u4(thread_serial_num); } else { hprof_printf("ROOT %x (kind=<thread block>, thread=%u)\n", objmap, thread_serial_num); } break; } case HPROF_GC_ROOT_MONITOR_USED: { void *h = hprof_dump_read_id(); hprof_objmap_t *objmap = hprof_fetch_object_info(h); if (output_format == 'b') { hprof_write_id(objmap); } else { hprof_printf("ROOT %x (kind=<busy monitor>)\n", objmap); } break; } case HPROF_GC_ROOT_JNI_LOCAL: { void *h = hprof_dump_read_id(); hprof_objmap_t *objmap = hprof_fetch_object_info(h); void *env = hprof_dump_read_id(); int depth = hprof_dump_read_u4(); hprof_thread_t *thread = hprof_lookup_thread(env); unsigned int thread_serial_num = (thread == NULL) ? 0 : thread->serial_num; if (output_format == 'b') { hprof_write_id(objmap); hprof_write_u4(thread_serial_num); hprof_write_u4(depth); } else { hprof_printf("ROOT %x (kind=<JNI local ref>, " "thread=%u, frame=%d)\n", objmap, thread_serial_num, depth); } break; } case HPROF_GC_ROOT_JAVA_FRAME: { void *h = hprof_dump_read_id(); hprof_objmap_t *objmap = hprof_fetch_object_info(h); void *env = hprof_dump_read_id(); int depth = hprof_dump_read_u4(); hprof_thread_t *thread = hprof_lookup_thread(env); unsigned int thread_serial_num = (thread == NULL) ? 0 : thread->serial_num; if (output_format == 'b') { hprof_write_id(objmap); hprof_write_u4(thread_serial_num); hprof_write_u4(depth); } else { hprof_printf("ROOT %x (kind=<Java stack>, " "thread=%u, frame=%d)\n", objmap, thread_serial_num, depth); } break; } case HPROF_GC_CLASS_DUMP: { void *class_id; hprof_objmap_t *class_map; hprof_objmap_t *super_map; hprof_objmap_t *loader_map; hprof_objmap_t *signers_map; hprof_objmap_t *domain_map; unsigned int trace_serial_num; hprof_class_t *class; const char *class_name; void *resv1; void *resv2; unsigned int size; unsigned short n; int i; class_id = hprof_dump_read_id(); class_map = hprof_fetch_object_info(class_id); class = hprof_lookup_class_objmap(class_map); if (class == NULL) { fprintf(stderr, "HPROF ERROR: unknown class_id in heap dump %p %p\n", class_id, class_map); return; } trace_serial_num = class_map->site->trace_serial_num; class_name = class->name->name; super_map = hprof_fetch_object_info(hprof_dump_read_id()); loader_map = hprof_fetch_object_info(hprof_dump_read_id()); signers_map = hprof_fetch_object_info(hprof_dump_read_id()); domain_map = hprof_fetch_object_info(hprof_dump_read_id()); resv1 = hprof_dump_read_id(); /* reserved */ resv2 = hprof_dump_read_id(); /* reserved */ size = hprof_dump_read_u4(); if (output_format == 'b') { hprof_write_id(class_map); hprof_write_u4(trace_serial_num); hprof_write_id(super_map); hprof_write_id(loader_map);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?