comparison src/share/vm/services/heapDumper.cpp @ 6197:d2a62e0f25eb

6995781: Native Memory Tracking (Phase 1) 7151532: DCmd for hotspot native memory tracking Summary: Implementation of native memory tracking phase 1, which tracks VM native memory usage, and related DCmd Reviewed-by: acorn, coleenp, fparain
author zgu
date Thu, 28 Jun 2012 17:03:16 -0400
parents 2ceafe3ceb65
children 1d7922586cf6
comparison
equal deleted inserted replaced
6174:74533f63b116 6197:d2a62e0f25eb
434 DumpWriter::DumpWriter(const char* path) { 434 DumpWriter::DumpWriter(const char* path) {
435 // try to allocate an I/O buffer of io_buffer_size. If there isn't 435 // try to allocate an I/O buffer of io_buffer_size. If there isn't
436 // sufficient memory then reduce size until we can allocate something. 436 // sufficient memory then reduce size until we can allocate something.
437 _size = io_buffer_size; 437 _size = io_buffer_size;
438 do { 438 do {
439 _buffer = (char*)os::malloc(_size); 439 _buffer = (char*)os::malloc(_size, mtInternal);
440 if (_buffer == NULL) { 440 if (_buffer == NULL) {
441 _size = _size >> 1; 441 _size = _size >> 1;
442 } 442 }
443 } while (_buffer == NULL && _size > 0); 443 } while (_buffer == NULL && _size > 0);
444 assert((_size > 0 && _buffer != NULL) || (_size == 0 && _buffer == NULL), "sanity check"); 444 assert((_size > 0 && _buffer != NULL) || (_size == 0 && _buffer == NULL), "sanity check");
1403 gc_before_heap_dump) { 1403 gc_before_heap_dump) {
1404 _local_writer = writer; 1404 _local_writer = writer;
1405 _gc_before_heap_dump = gc_before_heap_dump; 1405 _gc_before_heap_dump = gc_before_heap_dump;
1406 _is_segmented_dump = false; 1406 _is_segmented_dump = false;
1407 _dump_start = (jlong)-1; 1407 _dump_start = (jlong)-1;
1408 _klass_map = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, true); 1408 _klass_map = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, true);
1409 _stack_traces = NULL; 1409 _stack_traces = NULL;
1410 _num_threads = 0; 1410 _num_threads = 0;
1411 if (oome) { 1411 if (oome) {
1412 assert(!Thread::current()->is_VM_thread(), "Dump from OutOfMemoryError cannot be called by the VMThread"); 1412 assert(!Thread::current()->is_VM_thread(), "Dump from OutOfMemoryError cannot be called by the VMThread");
1413 // get OutOfMemoryError zero-parameter constructor 1413 // get OutOfMemoryError zero-parameter constructor
1424 ~VM_HeapDumper() { 1424 ~VM_HeapDumper() {
1425 if (_stack_traces != NULL) { 1425 if (_stack_traces != NULL) {
1426 for (int i=0; i < _num_threads; i++) { 1426 for (int i=0; i < _num_threads; i++) {
1427 delete _stack_traces[i]; 1427 delete _stack_traces[i];
1428 } 1428 }
1429 FREE_C_HEAP_ARRAY(ThreadStackTrace*, _stack_traces); 1429 FREE_C_HEAP_ARRAY(ThreadStackTrace*, _stack_traces, mtInternal);
1430 } 1430 }
1431 delete _klass_map; 1431 delete _klass_map;
1432 } 1432 }
1433 1433
1434 VMOp_Type type() const { return VMOp_HeapDumper; } 1434 VMOp_Type type() const { return VMOp_HeapDumper; }
1804 DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4)); 1804 DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4));
1805 writer()->write_u4((u4) STACK_TRACE_ID); 1805 writer()->write_u4((u4) STACK_TRACE_ID);
1806 writer()->write_u4(0); // thread number 1806 writer()->write_u4(0); // thread number
1807 writer()->write_u4(0); // frame count 1807 writer()->write_u4(0); // frame count
1808 1808
1809 _stack_traces = NEW_C_HEAP_ARRAY(ThreadStackTrace*, Threads::number_of_threads()); 1809 _stack_traces = NEW_C_HEAP_ARRAY(ThreadStackTrace*, Threads::number_of_threads(), mtInternal);
1810 int frame_serial_num = 0; 1810 int frame_serial_num = 0;
1811 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) { 1811 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
1812 oop threadObj = thread->threadObj(); 1812 oop threadObj = thread->threadObj();
1813 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) { 1813 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
1814 // dump thread stack trace 1814 // dump thread stack trace
2003 const size_t dlen = strlen(base_path); // if heap dump dir specified 2003 const size_t dlen = strlen(base_path); // if heap dump dir specified
2004 jio_snprintf(&base_path[dlen], sizeof(base_path)-dlen, "%s%d%s", 2004 jio_snprintf(&base_path[dlen], sizeof(base_path)-dlen, "%s%d%s",
2005 dump_file_name, os::current_process_id(), dump_file_ext); 2005 dump_file_name, os::current_process_id(), dump_file_ext);
2006 } 2006 }
2007 const size_t len = strlen(base_path) + 1; 2007 const size_t len = strlen(base_path) + 1;
2008 my_path = (char*)os::malloc(len); 2008 my_path = (char*)os::malloc(len, mtInternal);
2009 if (my_path == NULL) { 2009 if (my_path == NULL) {
2010 warning("Cannot create heap dump file. Out of system memory."); 2010 warning("Cannot create heap dump file. Out of system memory.");
2011 return; 2011 return;
2012 } 2012 }
2013 strncpy(my_path, base_path, len); 2013 strncpy(my_path, base_path, len);
2014 } else { 2014 } else {
2015 // Append a sequence number id for dumps following the first 2015 // Append a sequence number id for dumps following the first
2016 const size_t len = strlen(base_path) + max_digit_chars + 2; // for '.' and \0 2016 const size_t len = strlen(base_path) + max_digit_chars + 2; // for '.' and \0
2017 my_path = (char*)os::malloc(len); 2017 my_path = (char*)os::malloc(len, mtInternal);
2018 if (my_path == NULL) { 2018 if (my_path == NULL) {
2019 warning("Cannot create heap dump file. Out of system memory."); 2019 warning("Cannot create heap dump file. Out of system memory.");
2020 return; 2020 return;
2021 } 2021 }
2022 jio_snprintf(my_path, len, "%s.%d", base_path, dump_file_seq); 2022 jio_snprintf(my_path, len, "%s.%d", base_path, dump_file_seq);