28 #include "gc/shared/barrierSet.inline.hpp" |
28 #include "gc/shared/barrierSet.inline.hpp" |
29 #include "gc/shared/collectedHeap.hpp" |
29 #include "gc/shared/collectedHeap.hpp" |
30 #include "gc/shared/collectedHeap.inline.hpp" |
30 #include "gc/shared/collectedHeap.inline.hpp" |
31 #include "gc/shared/gcHeapSummary.hpp" |
31 #include "gc/shared/gcHeapSummary.hpp" |
32 #include "gc/shared/gcTrace.hpp" |
32 #include "gc/shared/gcTrace.hpp" |
33 #include "gc/shared/gcTraceTime.hpp" |
33 #include "gc/shared/gcTraceTime.inline.hpp" |
34 #include "gc/shared/gcWhen.hpp" |
34 #include "gc/shared/gcWhen.hpp" |
35 #include "gc/shared/vmGCOperations.hpp" |
35 #include "gc/shared/vmGCOperations.hpp" |
|
36 #include "logging/log.hpp" |
36 #include "memory/metaspace.hpp" |
37 #include "memory/metaspace.hpp" |
37 #include "oops/instanceMirrorKlass.hpp" |
38 #include "oops/instanceMirrorKlass.hpp" |
38 #include "oops/oop.inline.hpp" |
39 #include "oops/oop.inline.hpp" |
39 #include "runtime/init.hpp" |
40 #include "runtime/init.hpp" |
40 #include "runtime/thread.inline.hpp" |
41 #include "runtime/thread.inline.hpp" |
63 int index = compute_log_index(); |
64 int index = compute_log_index(); |
64 _records[index].thread = NULL; // Its the GC thread so it's not that interesting. |
65 _records[index].thread = NULL; // Its the GC thread so it's not that interesting. |
65 _records[index].timestamp = timestamp; |
66 _records[index].timestamp = timestamp; |
66 _records[index].data.is_before = before; |
67 _records[index].data.is_before = before; |
67 stringStream st(_records[index].data.buffer(), _records[index].data.size()); |
68 stringStream st(_records[index].data.buffer(), _records[index].data.size()); |
68 if (before) { |
69 |
69 Universe::print_heap_before_gc(&st, true); |
70 st.print_cr("{Heap %s GC invocations=%u (full %u):", |
70 } else { |
71 before ? "before" : "after", |
71 Universe::print_heap_after_gc(&st, true); |
72 heap->total_collections(), |
72 } |
73 heap->total_full_collections()); |
|
74 |
|
75 heap->print_on(&st); |
|
76 st.print_cr("}"); |
73 } |
77 } |
74 |
78 |
75 VirtualSpaceSummary CollectedHeap::create_heap_space_summary() { |
79 VirtualSpaceSummary CollectedHeap::create_heap_space_summary() { |
76 size_t capacity_in_words = capacity() / HeapWordSize; |
80 size_t capacity_in_words = capacity() / HeapWordSize; |
77 |
81 |
106 return MetaspaceSummary(MetaspaceGC::capacity_until_GC(), meta_space, data_space, class_space, |
110 return MetaspaceSummary(MetaspaceGC::capacity_until_GC(), meta_space, data_space, class_space, |
107 ms_chunk_free_list_summary, class_chunk_free_list_summary); |
111 ms_chunk_free_list_summary, class_chunk_free_list_summary); |
108 } |
112 } |
109 |
113 |
110 void CollectedHeap::print_heap_before_gc() { |
114 void CollectedHeap::print_heap_before_gc() { |
111 if (PrintHeapAtGC) { |
115 Universe::print_heap_before_gc(); |
112 Universe::print_heap_before_gc(); |
|
113 } |
|
114 if (_gc_heap_log != NULL) { |
116 if (_gc_heap_log != NULL) { |
115 _gc_heap_log->log_heap_before(); |
117 _gc_heap_log->log_heap_before(this); |
116 } |
118 } |
117 } |
119 } |
118 |
120 |
119 void CollectedHeap::print_heap_after_gc() { |
121 void CollectedHeap::print_heap_after_gc() { |
120 if (PrintHeapAtGC) { |
122 Universe::print_heap_after_gc(); |
121 Universe::print_heap_after_gc(); |
|
122 } |
|
123 if (_gc_heap_log != NULL) { |
123 if (_gc_heap_log != NULL) { |
124 _gc_heap_log->log_heap_after(); |
124 _gc_heap_log->log_heap_after(this); |
125 } |
125 } |
126 } |
126 } |
127 |
127 |
128 void CollectedHeap::print_on_error(outputStream* st) const { |
128 void CollectedHeap::print_on_error(outputStream* st) const { |
129 st->print_cr("Heap:"); |
129 st->print_cr("Heap:"); |
569 |
569 |
570 ThreadLocalAllocBuffer::resize_all_tlabs(); |
570 ThreadLocalAllocBuffer::resize_all_tlabs(); |
571 } |
571 } |
572 } |
572 } |
573 |
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 |
574 void CollectedHeap::pre_full_gc_dump(GCTimer* timer) { |
592 void CollectedHeap::pre_full_gc_dump(GCTimer* timer) { |
575 if (HeapDumpBeforeFullGC) { |
593 full_gc_dump(timer, "before"); |
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 } |
594 } |
589 |
595 |
590 void CollectedHeap::post_full_gc_dump(GCTimer* timer) { |
596 void CollectedHeap::post_full_gc_dump(GCTimer* timer) { |
591 if (HeapDumpAfterFullGC) { |
597 full_gc_dump(timer, "after"); |
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 } |
598 } |
603 |
599 |
604 void CollectedHeap::initialize_reserved_region(HeapWord *start, HeapWord *end) { |
600 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 |
601 // 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.) |
602 // temporarily think something is in the heap. (Seen this happen in asserts.) |