21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/parallel/adjoiningGenerations.hpp"
27 #include "gc/parallel/adjoiningVirtualSpaces.hpp"
28 #include "gc/parallel/cardTableExtension.hpp"
29 #include "gc/parallel/gcTaskManager.hpp"
30 #include "gc/parallel/generationSizer.hpp"
31 #include "gc/parallel/parallelScavengeHeap.inline.hpp"
32 #include "gc/parallel/psAdaptiveSizePolicy.hpp"
33 #include "gc/parallel/psMarkSweep.hpp"
34 #include "gc/parallel/psParallelCompact.hpp"
35 #include "gc/parallel/psPromotionManager.hpp"
36 #include "gc/parallel/psScavenge.hpp"
37 #include "gc/parallel/vmPSOperations.hpp"
38 #include "gc/shared/gcHeapSummary.hpp"
39 #include "gc/shared/gcLocker.inline.hpp"
40 #include "gc/shared/gcWhen.hpp"
41 #include "oops/oop.inline.hpp"
42 #include "runtime/handles.inline.hpp"
43 #include "runtime/java.hpp"
44 #include "runtime/vmThread.hpp"
45 #include "services/memTracker.hpp"
46 #include "utilities/vmError.hpp"
47
48 PSYoungGen* ParallelScavengeHeap::_young_gen = NULL;
49 PSOldGen* ParallelScavengeHeap::_old_gen = NULL;
50 PSAdaptiveSizePolicy* ParallelScavengeHeap::_size_policy = NULL;
51 PSGCAdaptivePolicyCounters* ParallelScavengeHeap::_gc_policy_counters = NULL;
52 GCTaskManager* ParallelScavengeHeap::_gc_task_manager = NULL;
53
54 jint ParallelScavengeHeap::initialize() {
55 CollectedHeap::pre_initialize();
56
57 const size_t heap_size = _collector_policy->max_heap_byte_size();
58
59 ReservedSpace heap_rs = Universe::reserve_heap(heap_size, _collector_policy->heap_alignment());
60
290 continue; // retry and/or stall as necessary
291 }
292
293 // Exit the loop if the gc time limit has been exceeded.
294 // The allocation must have failed above ("result" guarding
295 // this path is NULL) and the most recent collection has exceeded the
296 // gc overhead limit (although enough may have been collected to
297 // satisfy the allocation). Exit the loop so that an out-of-memory
298 // will be thrown (return a NULL ignoring the contents of
299 // op.result()),
300 // but clear gc_overhead_limit_exceeded so that the next collection
301 // starts with a clean slate (i.e., forgets about previous overhead
302 // excesses). Fill op.result() with a filler object so that the
303 // heap remains parsable.
304 const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
305 const bool softrefs_clear = collector_policy()->all_soft_refs_clear();
306
307 if (limit_exceeded && softrefs_clear) {
308 *gc_overhead_limit_was_exceeded = true;
309 size_policy()->set_gc_overhead_limit_exceeded(false);
310 if (PrintGCDetails && Verbose) {
311 gclog_or_tty->print_cr("ParallelScavengeHeap::mem_allocate: "
312 "return NULL because gc_overhead_limit_exceeded is set");
313 }
314 if (op.result() != NULL) {
315 CollectedHeap::fill_with_object(op.result(), size);
316 }
317 return NULL;
318 }
319
320 return op.result();
321 }
322 }
323
324 // The policy object will prevent us from looping forever. If the
325 // time spent in gc crosses a threshold, we will bail out.
326 loop_count++;
327 if ((result == NULL) && (QueuedAllocationWarningCount > 0) &&
328 (loop_count % QueuedAllocationWarningCount == 0)) {
329 warning("ParallelScavengeHeap::mem_allocate retries %d times \n\t"
330 " size=" SIZE_FORMAT, loop_count, size);
331 }
332 }
333
567 void ParallelScavengeHeap::gc_threads_do(ThreadClosure* tc) const {
568 PSScavenge::gc_task_manager()->threads_do(tc);
569 }
570
571 void ParallelScavengeHeap::print_gc_threads_on(outputStream* st) const {
572 PSScavenge::gc_task_manager()->print_threads_on(st);
573 }
574
575 void ParallelScavengeHeap::print_tracing_info() const {
576 if (TraceYoungGenTime) {
577 double time = PSScavenge::accumulated_time()->seconds();
578 tty->print_cr("[Accumulated GC generation 0 time %3.7f secs]", time);
579 }
580 if (TraceOldGenTime) {
581 double time = UseParallelOldGC ? PSParallelCompact::accumulated_time()->seconds() : PSMarkSweep::accumulated_time()->seconds();
582 tty->print_cr("[Accumulated GC generation 1 time %3.7f secs]", time);
583 }
584 }
585
586
587 void ParallelScavengeHeap::verify(bool silent, VerifyOption option /* ignored */) {
588 // Why do we need the total_collections()-filter below?
589 if (total_collections() > 0) {
590 if (!silent) {
591 gclog_or_tty->print("tenured ");
592 }
593 old_gen()->verify();
594
595 if (!silent) {
596 gclog_or_tty->print("eden ");
597 }
598 young_gen()->verify();
599 }
600 }
601
602 void ParallelScavengeHeap::print_heap_change(size_t prev_used) {
603 if (PrintGCDetails && Verbose) {
604 gclog_or_tty->print(" " SIZE_FORMAT
605 "->" SIZE_FORMAT
606 "(" SIZE_FORMAT ")",
607 prev_used, used(), capacity());
608 } else {
609 gclog_or_tty->print(" " SIZE_FORMAT "K"
610 "->" SIZE_FORMAT "K"
611 "(" SIZE_FORMAT "K)",
612 prev_used / K, used() / K, capacity() / K);
613 }
614 }
615
616 void ParallelScavengeHeap::trace_heap(GCWhen::Type when, const GCTracer* gc_tracer) {
617 const PSHeapSummary& heap_summary = create_ps_heap_summary();
618 gc_tracer->report_gc_heap_summary(when, heap_summary);
619
620 const MetaspaceSummary& metaspace_summary = create_metaspace_summary();
621 gc_tracer->report_metaspace_summary(when, metaspace_summary);
622 }
623
624 ParallelScavengeHeap* ParallelScavengeHeap::heap() {
625 CollectedHeap* heap = Universe::heap();
626 assert(heap != NULL, "Uninitialized access to ParallelScavengeHeap::heap()");
627 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Not a ParallelScavengeHeap");
628 return (ParallelScavengeHeap*)heap;
629 }
630
631 // Before delegating the resize to the young generation,
632 // the reserved space for the young and old generations
|
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/parallel/adjoiningGenerations.hpp"
27 #include "gc/parallel/adjoiningVirtualSpaces.hpp"
28 #include "gc/parallel/cardTableExtension.hpp"
29 #include "gc/parallel/gcTaskManager.hpp"
30 #include "gc/parallel/generationSizer.hpp"
31 #include "gc/parallel/parallelScavengeHeap.inline.hpp"
32 #include "gc/parallel/psAdaptiveSizePolicy.hpp"
33 #include "gc/parallel/psMarkSweep.hpp"
34 #include "gc/parallel/psParallelCompact.hpp"
35 #include "gc/parallel/psPromotionManager.hpp"
36 #include "gc/parallel/psScavenge.hpp"
37 #include "gc/parallel/vmPSOperations.hpp"
38 #include "gc/shared/gcHeapSummary.hpp"
39 #include "gc/shared/gcLocker.inline.hpp"
40 #include "gc/shared/gcWhen.hpp"
41 #include "logging/log.hpp"
42 #include "oops/oop.inline.hpp"
43 #include "runtime/handles.inline.hpp"
44 #include "runtime/java.hpp"
45 #include "runtime/vmThread.hpp"
46 #include "services/memTracker.hpp"
47 #include "utilities/vmError.hpp"
48
49 PSYoungGen* ParallelScavengeHeap::_young_gen = NULL;
50 PSOldGen* ParallelScavengeHeap::_old_gen = NULL;
51 PSAdaptiveSizePolicy* ParallelScavengeHeap::_size_policy = NULL;
52 PSGCAdaptivePolicyCounters* ParallelScavengeHeap::_gc_policy_counters = NULL;
53 GCTaskManager* ParallelScavengeHeap::_gc_task_manager = NULL;
54
55 jint ParallelScavengeHeap::initialize() {
56 CollectedHeap::pre_initialize();
57
58 const size_t heap_size = _collector_policy->max_heap_byte_size();
59
60 ReservedSpace heap_rs = Universe::reserve_heap(heap_size, _collector_policy->heap_alignment());
61
291 continue; // retry and/or stall as necessary
292 }
293
294 // Exit the loop if the gc time limit has been exceeded.
295 // The allocation must have failed above ("result" guarding
296 // this path is NULL) and the most recent collection has exceeded the
297 // gc overhead limit (although enough may have been collected to
298 // satisfy the allocation). Exit the loop so that an out-of-memory
299 // will be thrown (return a NULL ignoring the contents of
300 // op.result()),
301 // but clear gc_overhead_limit_exceeded so that the next collection
302 // starts with a clean slate (i.e., forgets about previous overhead
303 // excesses). Fill op.result() with a filler object so that the
304 // heap remains parsable.
305 const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
306 const bool softrefs_clear = collector_policy()->all_soft_refs_clear();
307
308 if (limit_exceeded && softrefs_clear) {
309 *gc_overhead_limit_was_exceeded = true;
310 size_policy()->set_gc_overhead_limit_exceeded(false);
311 log_trace(gc)("ParallelScavengeHeap::mem_allocate: return NULL because gc_overhead_limit_exceeded is set");
312 if (op.result() != NULL) {
313 CollectedHeap::fill_with_object(op.result(), size);
314 }
315 return NULL;
316 }
317
318 return op.result();
319 }
320 }
321
322 // The policy object will prevent us from looping forever. If the
323 // time spent in gc crosses a threshold, we will bail out.
324 loop_count++;
325 if ((result == NULL) && (QueuedAllocationWarningCount > 0) &&
326 (loop_count % QueuedAllocationWarningCount == 0)) {
327 warning("ParallelScavengeHeap::mem_allocate retries %d times \n\t"
328 " size=" SIZE_FORMAT, loop_count, size);
329 }
330 }
331
565 void ParallelScavengeHeap::gc_threads_do(ThreadClosure* tc) const {
566 PSScavenge::gc_task_manager()->threads_do(tc);
567 }
568
569 void ParallelScavengeHeap::print_gc_threads_on(outputStream* st) const {
570 PSScavenge::gc_task_manager()->print_threads_on(st);
571 }
572
573 void ParallelScavengeHeap::print_tracing_info() const {
574 if (TraceYoungGenTime) {
575 double time = PSScavenge::accumulated_time()->seconds();
576 tty->print_cr("[Accumulated GC generation 0 time %3.7f secs]", time);
577 }
578 if (TraceOldGenTime) {
579 double time = UseParallelOldGC ? PSParallelCompact::accumulated_time()->seconds() : PSMarkSweep::accumulated_time()->seconds();
580 tty->print_cr("[Accumulated GC generation 1 time %3.7f secs]", time);
581 }
582 }
583
584
585 void ParallelScavengeHeap::verify(VerifyOption option /* ignored */) {
586 // Why do we need the total_collections()-filter below?
587 if (total_collections() > 0) {
588 log_debug(gc, verify)("Tenured");
589 old_gen()->verify();
590
591 log_debug(gc, verify)("Eden");
592 young_gen()->verify();
593 }
594 }
595
596 void ParallelScavengeHeap::trace_heap(GCWhen::Type when, const GCTracer* gc_tracer) {
597 const PSHeapSummary& heap_summary = create_ps_heap_summary();
598 gc_tracer->report_gc_heap_summary(when, heap_summary);
599
600 const MetaspaceSummary& metaspace_summary = create_metaspace_summary();
601 gc_tracer->report_metaspace_summary(when, metaspace_summary);
602 }
603
604 ParallelScavengeHeap* ParallelScavengeHeap::heap() {
605 CollectedHeap* heap = Universe::heap();
606 assert(heap != NULL, "Uninitialized access to ParallelScavengeHeap::heap()");
607 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Not a ParallelScavengeHeap");
608 return (ParallelScavengeHeap*)heap;
609 }
610
611 // Before delegating the resize to the young generation,
612 // the reserved space for the young and old generations
|