16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "classfile/systemDictionary.hpp" 27 #include "gc/shared/allocTracer.hpp" 28 #include "gc/shared/barrierSet.inline.hpp" 29 #include "gc/shared/collectedHeap.hpp" 30 #include "gc/shared/collectedHeap.inline.hpp" 31 #include "gc/shared/gcHeapSummary.hpp" 32 #include "gc/shared/gcTrace.hpp" 33 #include "gc/shared/gcTraceTime.hpp" 34 #include "gc/shared/gcWhen.hpp" 35 #include "gc/shared/vmGCOperations.hpp" 36 #include "memory/metaspace.hpp" 37 #include "oops/instanceMirrorKlass.hpp" 38 #include "oops/oop.inline.hpp" 39 #include "runtime/init.hpp" 40 #include "runtime/thread.inline.hpp" 41 #include "services/heapDumper.hpp" 42 43 44 #ifdef ASSERT 45 int CollectedHeap::_fire_out_of_memory_count = 0; 46 #endif 47 48 size_t CollectedHeap::_filler_array_max_size = 0; 49 50 template <> 51 void EventLogBase<GCMessage>::print(outputStream* st, GCMessage& m) { 52 st->print_cr("GC heap %s", m.is_before ? "before" : "after"); 53 st->print_raw(m); 54 } 55 56 void GCHeapLog::log_heap(bool before) { 57 if (!should_log()) { 58 return; 59 } 60 61 double timestamp = fetch_timestamp(); 62 MutexLockerEx ml(&_mutex, Mutex::_no_safepoint_check_flag); 63 int index = compute_log_index(); 64 _records[index].thread = NULL; // Its the GC thread so it's not that interesting. 65 _records[index].timestamp = timestamp; 66 _records[index].data.is_before = before; 67 stringStream st(_records[index].data.buffer(), _records[index].data.size()); 68 if (before) { 69 Universe::print_heap_before_gc(&st, true); 70 } else { 71 Universe::print_heap_after_gc(&st, true); 72 } 73 } 74 75 VirtualSpaceSummary CollectedHeap::create_heap_space_summary() { 76 size_t capacity_in_words = capacity() / HeapWordSize; 77 78 return VirtualSpaceSummary( 79 reserved_region().start(), reserved_region().start() + capacity_in_words, reserved_region().end()); 80 } 81 82 GCHeapSummary CollectedHeap::create_heap_summary() { 83 VirtualSpaceSummary heap_space = create_heap_space_summary(); 84 return GCHeapSummary(heap_space, used()); 85 } 86 87 MetaspaceSummary CollectedHeap::create_metaspace_summary() { 88 const MetaspaceSizes meta_space( 89 MetaspaceAux::committed_bytes(), 90 MetaspaceAux::used_bytes(), 91 MetaspaceAux::reserved_bytes()); 92 const MetaspaceSizes data_space( 93 MetaspaceAux::committed_bytes(Metaspace::NonClassType), 94 MetaspaceAux::used_bytes(Metaspace::NonClassType), 95 MetaspaceAux::reserved_bytes(Metaspace::NonClassType)); 96 const MetaspaceSizes class_space( 97 MetaspaceAux::committed_bytes(Metaspace::ClassType), 98 MetaspaceAux::used_bytes(Metaspace::ClassType), 99 MetaspaceAux::reserved_bytes(Metaspace::ClassType)); 100 101 const MetaspaceChunkFreeListSummary& ms_chunk_free_list_summary = 102 MetaspaceAux::chunk_free_list_summary(Metaspace::NonClassType); 103 const MetaspaceChunkFreeListSummary& class_chunk_free_list_summary = 104 MetaspaceAux::chunk_free_list_summary(Metaspace::ClassType); 105 106 return MetaspaceSummary(MetaspaceGC::capacity_until_GC(), meta_space, data_space, class_space, 107 ms_chunk_free_list_summary, class_chunk_free_list_summary); 108 } 109 110 void CollectedHeap::print_heap_before_gc() { 111 if (PrintHeapAtGC) { 112 Universe::print_heap_before_gc(); 113 } 114 if (_gc_heap_log != NULL) { 115 _gc_heap_log->log_heap_before(); 116 } 117 } 118 119 void CollectedHeap::print_heap_after_gc() { 120 if (PrintHeapAtGC) { 121 Universe::print_heap_after_gc(); 122 } 123 if (_gc_heap_log != NULL) { 124 _gc_heap_log->log_heap_after(); 125 } 126 } 127 128 void CollectedHeap::print_on_error(outputStream* st) const { 129 st->print_cr("Heap:"); 130 print_extended_on(st); 131 st->cr(); 132 133 _barrier_set->print_on(st); 134 } 135 136 void CollectedHeap::register_nmethod(nmethod* nm) { 137 assert_locked_or_safepoint(CodeCache_lock); 138 } 139 140 void CollectedHeap::unregister_nmethod(nmethod* nm) { 141 assert_locked_or_safepoint(CodeCache_lock); 142 } 143 144 void CollectedHeap::trace_heap(GCWhen::Type when, const GCTracer* gc_tracer) { 554 void CollectedHeap::accumulate_statistics_all_tlabs() { 555 if (UseTLAB) { 556 assert(SafepointSynchronize::is_at_safepoint() || 557 !is_init_completed(), 558 "should only accumulate statistics on tlabs at safepoint"); 559 560 ThreadLocalAllocBuffer::accumulate_statistics_before_gc(); 561 } 562 } 563 564 void CollectedHeap::resize_all_tlabs() { 565 if (UseTLAB) { 566 assert(SafepointSynchronize::is_at_safepoint() || 567 !is_init_completed(), 568 "should only resize tlabs at safepoint"); 569 570 ThreadLocalAllocBuffer::resize_all_tlabs(); 571 } 572 } 573 574 void CollectedHeap::pre_full_gc_dump(GCTimer* timer) { 575 if (HeapDumpBeforeFullGC) { 576 GCIdMarkAndRestore gc_id_mark; 577 GCTraceTime tt("Heap Dump (before full gc): ", PrintGCDetails, false, timer); 578 // We are doing a full collection and a heap dump before 579 // full collection has been requested. 580 HeapDumper::dump_heap(); 581 } 582 if (PrintClassHistogramBeforeFullGC) { 583 GCIdMarkAndRestore gc_id_mark; 584 GCTraceTime tt("Class Histogram (before full gc): ", PrintGCDetails, true, timer); 585 VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */); 586 inspector.doit(); 587 } 588 } 589 590 void CollectedHeap::post_full_gc_dump(GCTimer* timer) { 591 if (HeapDumpAfterFullGC) { 592 GCIdMarkAndRestore gc_id_mark; 593 GCTraceTime tt("Heap Dump (after full gc): ", PrintGCDetails, false, timer); 594 HeapDumper::dump_heap(); 595 } 596 if (PrintClassHistogramAfterFullGC) { 597 GCIdMarkAndRestore gc_id_mark; 598 GCTraceTime tt("Class Histogram (after full gc): ", PrintGCDetails, true, timer); 599 VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */); 600 inspector.doit(); 601 } 602 } 603 604 void CollectedHeap::initialize_reserved_region(HeapWord *start, HeapWord *end) { 605 // It is important to do this in a way such that concurrent readers can't 606 // temporarily think something is in the heap. (Seen this happen in asserts.) 607 _reserved.set_word_size(0); 608 _reserved.set_start(start); 609 _reserved.set_end(end); 610 } 611 612 /////////////// Unit tests /////////////// 613 614 #ifndef PRODUCT 615 void CollectedHeap::test_is_in() { 616 CollectedHeap* heap = Universe::heap(); 617 618 uintptr_t epsilon = (uintptr_t) MinObjAlignment; 619 uintptr_t heap_start = (uintptr_t) heap->_reserved.start(); 620 uintptr_t heap_end = (uintptr_t) heap->_reserved.end(); 621 | 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "classfile/systemDictionary.hpp" 27 #include "gc/shared/allocTracer.hpp" 28 #include "gc/shared/barrierSet.inline.hpp" 29 #include "gc/shared/collectedHeap.hpp" 30 #include "gc/shared/collectedHeap.inline.hpp" 31 #include "gc/shared/gcHeapSummary.hpp" 32 #include "gc/shared/gcTrace.hpp" 33 #include "gc/shared/gcTraceTime.hpp" 34 #include "gc/shared/gcWhen.hpp" 35 #include "gc/shared/vmGCOperations.hpp" 36 #include "logging/log.hpp" 37 #include "memory/metaspace.hpp" 38 #include "oops/instanceMirrorKlass.hpp" 39 #include "oops/oop.inline.hpp" 40 #include "runtime/init.hpp" 41 #include "runtime/thread.inline.hpp" 42 #include "services/heapDumper.hpp" 43 44 45 #ifdef ASSERT 46 int CollectedHeap::_fire_out_of_memory_count = 0; 47 #endif 48 49 size_t CollectedHeap::_filler_array_max_size = 0; 50 51 template <> 52 void EventLogBase<GCMessage>::print(outputStream* st, GCMessage& m) { 53 st->print_cr("GC heap %s", m.is_before ? "before" : "after"); 54 st->print_raw(m); 55 } 56 57 void GCHeapLog::log_heap(CollectedHeap* heap, bool before) { 58 if (!should_log()) { 59 return; 60 } 61 62 double timestamp = fetch_timestamp(); 63 MutexLockerEx ml(&_mutex, Mutex::_no_safepoint_check_flag); 64 int index = compute_log_index(); 65 _records[index].thread = NULL; // Its the GC thread so it's not that interesting. 66 _records[index].timestamp = timestamp; 67 _records[index].data.is_before = before; 68 stringStream st(_records[index].data.buffer(), _records[index].data.size()); 69 70 st.print_cr("{Heap %s GC invocations=%u (full %u):", 71 before ? "before" : "after", 72 heap->total_collections(), 73 heap->total_full_collections()); 74 75 heap->print_on(&st); 76 st.print_cr("}"); 77 } 78 79 VirtualSpaceSummary CollectedHeap::create_heap_space_summary() { 80 size_t capacity_in_words = capacity() / HeapWordSize; 81 82 return VirtualSpaceSummary( 83 reserved_region().start(), reserved_region().start() + capacity_in_words, reserved_region().end()); 84 } 85 86 GCHeapSummary CollectedHeap::create_heap_summary() { 87 VirtualSpaceSummary heap_space = create_heap_space_summary(); 88 return GCHeapSummary(heap_space, used()); 89 } 90 91 MetaspaceSummary CollectedHeap::create_metaspace_summary() { 92 const MetaspaceSizes meta_space( 93 MetaspaceAux::committed_bytes(), 94 MetaspaceAux::used_bytes(), 95 MetaspaceAux::reserved_bytes()); 96 const MetaspaceSizes data_space( 97 MetaspaceAux::committed_bytes(Metaspace::NonClassType), 98 MetaspaceAux::used_bytes(Metaspace::NonClassType), 99 MetaspaceAux::reserved_bytes(Metaspace::NonClassType)); 100 const MetaspaceSizes class_space( 101 MetaspaceAux::committed_bytes(Metaspace::ClassType), 102 MetaspaceAux::used_bytes(Metaspace::ClassType), 103 MetaspaceAux::reserved_bytes(Metaspace::ClassType)); 104 105 const MetaspaceChunkFreeListSummary& ms_chunk_free_list_summary = 106 MetaspaceAux::chunk_free_list_summary(Metaspace::NonClassType); 107 const MetaspaceChunkFreeListSummary& class_chunk_free_list_summary = 108 MetaspaceAux::chunk_free_list_summary(Metaspace::ClassType); 109 110 return MetaspaceSummary(MetaspaceGC::capacity_until_GC(), meta_space, data_space, class_space, 111 ms_chunk_free_list_summary, class_chunk_free_list_summary); 112 } 113 114 void CollectedHeap::print_heap_before_gc() { 115 Universe::print_heap_before_gc(); 116 if (_gc_heap_log != NULL) { 117 _gc_heap_log->log_heap_before(this); 118 } 119 } 120 121 void CollectedHeap::print_heap_after_gc() { 122 Universe::print_heap_after_gc(); 123 if (_gc_heap_log != NULL) { 124 _gc_heap_log->log_heap_after(this); 125 } 126 } 127 128 void CollectedHeap::print_on_error(outputStream* st) const { 129 st->print_cr("Heap:"); 130 print_extended_on(st); 131 st->cr(); 132 133 _barrier_set->print_on(st); 134 } 135 136 void CollectedHeap::register_nmethod(nmethod* nm) { 137 assert_locked_or_safepoint(CodeCache_lock); 138 } 139 140 void CollectedHeap::unregister_nmethod(nmethod* nm) { 141 assert_locked_or_safepoint(CodeCache_lock); 142 } 143 144 void CollectedHeap::trace_heap(GCWhen::Type when, const GCTracer* gc_tracer) { 554 void CollectedHeap::accumulate_statistics_all_tlabs() { 555 if (UseTLAB) { 556 assert(SafepointSynchronize::is_at_safepoint() || 557 !is_init_completed(), 558 "should only accumulate statistics on tlabs at safepoint"); 559 560 ThreadLocalAllocBuffer::accumulate_statistics_before_gc(); 561 } 562 } 563 564 void CollectedHeap::resize_all_tlabs() { 565 if (UseTLAB) { 566 assert(SafepointSynchronize::is_at_safepoint() || 567 !is_init_completed(), 568 "should only resize tlabs at safepoint"); 569 570 ThreadLocalAllocBuffer::resize_all_tlabs(); 571 } 572 } 573 574 void CollectedHeap::full_gc_dump(GCTimer* timer, const char* when) { 575 if (HeapDumpBeforeFullGC || HeapDumpAfterFullGC) { 576 GCIdMarkAndRestore gc_id_mark; 577 FormatBuffer<> title("Heap Dump (%s full gc)", when); 578 GCTraceTime(Info, gc) tm(title.buffer(), timer); 579 HeapDumper::dump_heap(); 580 } 581 LogHandle(gc, classhisto) log; 582 if (log.is_trace()) { 583 ResourceMark rm; 584 GCIdMarkAndRestore gc_id_mark; 585 FormatBuffer<> title("Class Histogram (%s full gc)", when); 586 GCTraceTime(Trace, gc, classhisto) tm(title.buffer(), timer); 587 VM_GC_HeapInspection inspector(log.trace_stream(), false /* ! full gc */); 588 inspector.doit(); 589 } 590 } 591 592 void CollectedHeap::pre_full_gc_dump(GCTimer* timer) { 593 full_gc_dump(timer, "before"); 594 } 595 596 void CollectedHeap::post_full_gc_dump(GCTimer* timer) { 597 full_gc_dump(timer, "after"); 598 } 599 600 void CollectedHeap::initialize_reserved_region(HeapWord *start, HeapWord *end) { 601 // It is important to do this in a way such that concurrent readers can't 602 // temporarily think something is in the heap. (Seen this happen in asserts.) 603 _reserved.set_word_size(0); 604 _reserved.set_start(start); 605 _reserved.set_end(end); 606 } 607 608 /////////////// Unit tests /////////////// 609 610 #ifndef PRODUCT 611 void CollectedHeap::test_is_in() { 612 CollectedHeap* heap = Universe::heap(); 613 614 uintptr_t epsilon = (uintptr_t) MinObjAlignment; 615 uintptr_t heap_start = (uintptr_t) heap->_reserved.start(); 616 uintptr_t heap_end = (uintptr_t) heap->_reserved.end(); 617 |