comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 3914:20213c8a3c40

7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions Summary: It introduces ergonomic decision logging in G1 for the following heuristics: heap sizing, collection set construction, concurrent cycle initiation, and partially-young GC start/end. The code has a bit of refactoring in a few places to make the decision logging possible. It also replaces alternative ad-hoc logging that we have under different parameters and switches (G1_DEBUG, G1PolicyVerbose). Reviewed-by: johnc, ysr
author tonyp
date Wed, 07 Sep 2011 12:21:23 -0400
parents eeae91c9baba
children 05550041d664
comparison
equal deleted inserted replaced
3913:27702f012017 3914:20213c8a3c40
29 #include "gc_implementation/g1/concurrentG1RefineThread.hpp" 29 #include "gc_implementation/g1/concurrentG1RefineThread.hpp"
30 #include "gc_implementation/g1/concurrentMarkThread.inline.hpp" 30 #include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
31 #include "gc_implementation/g1/g1AllocRegion.inline.hpp" 31 #include "gc_implementation/g1/g1AllocRegion.inline.hpp"
32 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" 32 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
33 #include "gc_implementation/g1/g1CollectorPolicy.hpp" 33 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
34 #include "gc_implementation/g1/g1ErgoVerbose.hpp"
34 #include "gc_implementation/g1/g1MarkSweep.hpp" 35 #include "gc_implementation/g1/g1MarkSweep.hpp"
35 #include "gc_implementation/g1/g1OopClosures.inline.hpp" 36 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
36 #include "gc_implementation/g1/g1RemSet.inline.hpp" 37 #include "gc_implementation/g1/g1RemSet.inline.hpp"
37 #include "gc_implementation/g1/heapRegionRemSet.hpp" 38 #include "gc_implementation/g1/heapRegionRemSet.hpp"
38 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" 39 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
575 "res == NULL, trying the secondary_free_list"); 576 "res == NULL, trying the secondary_free_list");
576 } 577 }
577 res = new_region_try_secondary_free_list(); 578 res = new_region_try_secondary_free_list();
578 } 579 }
579 if (res == NULL && do_expand) { 580 if (res == NULL && do_expand) {
581 ergo_verbose1(ErgoHeapSizing,
582 "attempt heap expansion",
583 ergo_format_reason("region allocation request failed")
584 ergo_format_byte("allocation request"),
585 word_size * HeapWordSize);
580 if (expand(word_size * HeapWordSize)) { 586 if (expand(word_size * HeapWordSize)) {
581 // Even though the heap was expanded, it might not have reached 587 // Even though the heap was expanded, it might not have reached
582 // the desired size. So, we cannot assume that the allocation 588 // the desired size. So, we cannot assume that the allocation
583 // will succeed. 589 // will succeed.
584 res = _free_list.remove_head_or_null(); 590 res = _free_list.remove_head_or_null();
788 // We should only be trying to expand when the free suffix is 794 // We should only be trying to expand when the free suffix is
789 // not sufficient for the object _and_ we have some expansion 795 // not sufficient for the object _and_ we have some expansion
790 // room available. 796 // room available.
791 assert(num_regions > fs, "earlier allocation should have succeeded"); 797 assert(num_regions > fs, "earlier allocation should have succeeded");
792 798
799 ergo_verbose1(ErgoHeapSizing,
800 "attempt heap expansion",
801 ergo_format_reason("humongous allocation request failed")
802 ergo_format_byte("allocation request"),
803 word_size * HeapWordSize);
793 if (expand((num_regions - fs) * HeapRegion::GrainBytes)) { 804 if (expand((num_regions - fs) * HeapRegion::GrainBytes)) {
794 // Even though the heap was expanded, it might not have 805 // Even though the heap was expanded, it might not have
795 // reached the desired size. So, we cannot assume that the 806 // reached the desired size. So, we cannot assume that the
796 // allocation will succeed. 807 // allocation will succeed.
797 first = humongous_obj_allocate_find_first(num_regions, word_size); 808 first = humongous_obj_allocate_find_first(num_regions, word_size);
904 // allocate a new region. So the mutator alloc region should be NULL. 915 // allocate a new region. So the mutator alloc region should be NULL.
905 assert(_mutator_alloc_region.get() == NULL, "only way to get here"); 916 assert(_mutator_alloc_region.get() == NULL, "only way to get here");
906 917
907 if (GC_locker::is_active_and_needs_gc()) { 918 if (GC_locker::is_active_and_needs_gc()) {
908 if (g1_policy()->can_expand_young_list()) { 919 if (g1_policy()->can_expand_young_list()) {
920 // No need for an ergo verbose message here,
921 // can_expand_young_list() does this when it returns true.
909 result = _mutator_alloc_region.attempt_allocation_force(word_size, 922 result = _mutator_alloc_region.attempt_allocation_force(word_size,
910 false /* bot_updates */); 923 false /* bot_updates */);
911 if (result != NULL) { 924 if (result != NULL) {
912 return result; 925 return result;
913 } 926 }
1475 // Should not be less than the heap min size. No need to adjust it 1488 // Should not be less than the heap min size. No need to adjust it
1476 // with respect to the heap max size as it's an upper bound (i.e., 1489 // with respect to the heap max size as it's an upper bound (i.e.,
1477 // we'll try to make the capacity smaller than it, not greater). 1490 // we'll try to make the capacity smaller than it, not greater).
1478 maximum_desired_capacity = MAX2(maximum_desired_capacity, min_heap_size); 1491 maximum_desired_capacity = MAX2(maximum_desired_capacity, min_heap_size);
1479 1492
1480 if (PrintGC && Verbose) {
1481 const double free_percentage =
1482 (double) free_after_gc / (double) capacity_after_gc;
1483 gclog_or_tty->print_cr("Computing new size after full GC ");
1484 gclog_or_tty->print_cr(" "
1485 " minimum_free_percentage: %6.2f",
1486 minimum_free_percentage);
1487 gclog_or_tty->print_cr(" "
1488 " maximum_free_percentage: %6.2f",
1489 maximum_free_percentage);
1490 gclog_or_tty->print_cr(" "
1491 " capacity: %6.1fK"
1492 " minimum_desired_capacity: %6.1fK"
1493 " maximum_desired_capacity: %6.1fK",
1494 (double) capacity_after_gc / (double) K,
1495 (double) minimum_desired_capacity / (double) K,
1496 (double) maximum_desired_capacity / (double) K);
1497 gclog_or_tty->print_cr(" "
1498 " free_after_gc: %6.1fK"
1499 " used_after_gc: %6.1fK",
1500 (double) free_after_gc / (double) K,
1501 (double) used_after_gc / (double) K);
1502 gclog_or_tty->print_cr(" "
1503 " free_percentage: %6.2f",
1504 free_percentage);
1505 }
1506 if (capacity_after_gc < minimum_desired_capacity) { 1493 if (capacity_after_gc < minimum_desired_capacity) {
1507 // Don't expand unless it's significant 1494 // Don't expand unless it's significant
1508 size_t expand_bytes = minimum_desired_capacity - capacity_after_gc; 1495 size_t expand_bytes = minimum_desired_capacity - capacity_after_gc;
1509 if (expand(expand_bytes)) { 1496 ergo_verbose4(ErgoHeapSizing,
1510 if (PrintGC && Verbose) { 1497 "attempt heap expansion",
1511 gclog_or_tty->print_cr(" " 1498 ergo_format_reason("capacity lower than "
1512 " expanding:" 1499 "min desired capacity after Full GC")
1513 " max_heap_size: %6.1fK" 1500 ergo_format_byte("capacity")
1514 " minimum_desired_capacity: %6.1fK" 1501 ergo_format_byte("occupancy")
1515 " expand_bytes: %6.1fK", 1502 ergo_format_byte_perc("min desired capacity"),
1516 (double) max_heap_size / (double) K, 1503 capacity_after_gc, used_after_gc,
1517 (double) minimum_desired_capacity / (double) K, 1504 minimum_desired_capacity, (double) MinHeapFreeRatio);
1518 (double) expand_bytes / (double) K); 1505 expand(expand_bytes);
1519 }
1520 }
1521 1506
1522 // No expansion, now see if we want to shrink 1507 // No expansion, now see if we want to shrink
1523 } else if (capacity_after_gc > maximum_desired_capacity) { 1508 } else if (capacity_after_gc > maximum_desired_capacity) {
1524 // Capacity too large, compute shrinking size 1509 // Capacity too large, compute shrinking size
1525 size_t shrink_bytes = capacity_after_gc - maximum_desired_capacity; 1510 size_t shrink_bytes = capacity_after_gc - maximum_desired_capacity;
1511 ergo_verbose4(ErgoHeapSizing,
1512 "attempt heap shrinking",
1513 ergo_format_reason("capacity higher than "
1514 "max desired capacity after Full GC")
1515 ergo_format_byte("capacity")
1516 ergo_format_byte("occupancy")
1517 ergo_format_byte_perc("max desired capacity"),
1518 capacity_after_gc, used_after_gc,
1519 maximum_desired_capacity, (double) MaxHeapFreeRatio);
1526 shrink(shrink_bytes); 1520 shrink(shrink_bytes);
1527 if (PrintGC && Verbose) {
1528 gclog_or_tty->print_cr(" "
1529 " shrinking:"
1530 " min_heap_size: %6.1fK"
1531 " maximum_desired_capacity: %6.1fK"
1532 " shrink_bytes: %6.1fK",
1533 (double) min_heap_size / (double) K,
1534 (double) maximum_desired_capacity / (double) K,
1535 (double) shrink_bytes / (double) K);
1536 }
1537 } 1521 }
1538 } 1522 }
1539 1523
1540 1524
1541 HeapWord* 1525 HeapWord*
1617 assert_at_safepoint(true /* should_be_vm_thread */); 1601 assert_at_safepoint(true /* should_be_vm_thread */);
1618 1602
1619 verify_region_sets_optional(); 1603 verify_region_sets_optional();
1620 1604
1621 size_t expand_bytes = MAX2(word_size * HeapWordSize, MinHeapDeltaBytes); 1605 size_t expand_bytes = MAX2(word_size * HeapWordSize, MinHeapDeltaBytes);
1606 ergo_verbose1(ErgoHeapSizing,
1607 "attempt heap expansion",
1608 ergo_format_reason("allocation request failed")
1609 ergo_format_byte("allocation request"),
1610 word_size * HeapWordSize);
1622 if (expand(expand_bytes)) { 1611 if (expand(expand_bytes)) {
1623 _hrs.verify_optional(); 1612 _hrs.verify_optional();
1624 verify_region_sets_optional(); 1613 verify_region_sets_optional();
1625 return attempt_allocation_at_safepoint(word_size, 1614 return attempt_allocation_at_safepoint(word_size,
1626 false /* expect_null_mutator_alloc_region */); 1615 false /* expect_null_mutator_alloc_region */);
1644 bool G1CollectedHeap::expand(size_t expand_bytes) { 1633 bool G1CollectedHeap::expand(size_t expand_bytes) {
1645 size_t old_mem_size = _g1_storage.committed_size(); 1634 size_t old_mem_size = _g1_storage.committed_size();
1646 size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); 1635 size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
1647 aligned_expand_bytes = align_size_up(aligned_expand_bytes, 1636 aligned_expand_bytes = align_size_up(aligned_expand_bytes,
1648 HeapRegion::GrainBytes); 1637 HeapRegion::GrainBytes);
1649 1638 ergo_verbose2(ErgoHeapSizing,
1650 if (Verbose && PrintGC) { 1639 "expand the heap",
1651 gclog_or_tty->print("Expanding garbage-first heap from %ldK by %ldK", 1640 ergo_format_byte("requested expansion amount")
1652 old_mem_size/K, aligned_expand_bytes/K); 1641 ergo_format_byte("attempted expansion amount"),
1653 } 1642 expand_bytes, aligned_expand_bytes);
1654 1643
1655 // First commit the memory. 1644 // First commit the memory.
1656 HeapWord* old_end = (HeapWord*) _g1_storage.high(); 1645 HeapWord* old_end = (HeapWord*) _g1_storage.high();
1657 bool successful = _g1_storage.expand_by(aligned_expand_bytes); 1646 bool successful = _g1_storage.expand_by(aligned_expand_bytes);
1658 if (successful) { 1647 if (successful) {
1692 curr = curr_end; 1681 curr = curr_end;
1693 } 1682 }
1694 assert(curr == mr.end(), "post-condition"); 1683 assert(curr == mr.end(), "post-condition");
1695 } 1684 }
1696 } else { 1685 } else {
1686 ergo_verbose0(ErgoHeapSizing,
1687 "did not expand the heap",
1688 ergo_format_reason("heap expansion operation failed"));
1697 // The expansion of the virtual storage space was unsuccessful. 1689 // The expansion of the virtual storage space was unsuccessful.
1698 // Let's see if it was because we ran out of swap. 1690 // Let's see if it was because we ran out of swap.
1699 if (G1ExitOnExpansionFailure && 1691 if (G1ExitOnExpansionFailure &&
1700 _g1_storage.uncommitted_size() >= aligned_expand_bytes) { 1692 _g1_storage.uncommitted_size() >= aligned_expand_bytes) {
1701 // We had head room... 1693 // We had head room...
1702 vm_exit_out_of_memory(aligned_expand_bytes, "G1 heap expansion"); 1694 vm_exit_out_of_memory(aligned_expand_bytes, "G1 heap expansion");
1703 } 1695 }
1704 }
1705
1706 if (Verbose && PrintGC) {
1707 size_t new_mem_size = _g1_storage.committed_size();
1708 gclog_or_tty->print_cr("...%s, expanded to %ldK",
1709 (successful ? "Successful" : "Failed"),
1710 new_mem_size/K);
1711 } 1696 }
1712 return successful; 1697 return successful;
1713 } 1698 }
1714 1699
1715 void G1CollectedHeap::shrink_helper(size_t shrink_bytes) { 1700 void G1CollectedHeap::shrink_helper(size_t shrink_bytes) {
1720 HeapRegion::GrainBytes); 1705 HeapRegion::GrainBytes);
1721 size_t num_regions_deleted = 0; 1706 size_t num_regions_deleted = 0;
1722 MemRegion mr = _hrs.shrink_by(aligned_shrink_bytes, &num_regions_deleted); 1707 MemRegion mr = _hrs.shrink_by(aligned_shrink_bytes, &num_regions_deleted);
1723 HeapWord* old_end = (HeapWord*) _g1_storage.high(); 1708 HeapWord* old_end = (HeapWord*) _g1_storage.high();
1724 assert(mr.end() == old_end, "post-condition"); 1709 assert(mr.end() == old_end, "post-condition");
1710
1711 ergo_verbose3(ErgoHeapSizing,
1712 "shrink the heap",
1713 ergo_format_byte("requested shrinking amount")
1714 ergo_format_byte("aligned shrinking amount")
1715 ergo_format_byte("attempted shrinking amount"),
1716 shrink_bytes, aligned_shrink_bytes, mr.byte_size());
1725 if (mr.byte_size() > 0) { 1717 if (mr.byte_size() > 0) {
1726 if (_hr_printer.is_active()) { 1718 if (_hr_printer.is_active()) {
1727 HeapWord* curr = mr.end(); 1719 HeapWord* curr = mr.end();
1728 while (curr > mr.start()) { 1720 while (curr > mr.start()) {
1729 HeapWord* curr_end = curr; 1721 HeapWord* curr_end = curr;
1738 assert(mr.start() == new_end, "post-condition"); 1730 assert(mr.start() == new_end, "post-condition");
1739 1731
1740 _expansion_regions += num_regions_deleted; 1732 _expansion_regions += num_regions_deleted;
1741 update_committed_space(old_end, new_end); 1733 update_committed_space(old_end, new_end);
1742 HeapRegionRemSet::shrink_heap(n_regions()); 1734 HeapRegionRemSet::shrink_heap(n_regions());
1743 1735 } else {
1744 if (Verbose && PrintGC) { 1736 ergo_verbose0(ErgoHeapSizing,
1745 size_t new_mem_size = _g1_storage.committed_size(); 1737 "did not shrink the heap",
1746 gclog_or_tty->print_cr("Shrinking garbage-first heap from %ldK by %ldK to %ldK", 1738 ergo_format_reason("heap shrinking operation failed"));
1747 old_mem_size/K, aligned_shrink_bytes/K,
1748 new_mem_size/K);
1749 }
1750 } 1739 }
1751 } 1740 }
1752 1741
1753 void G1CollectedHeap::shrink(size_t shrink_bytes) { 1742 void G1CollectedHeap::shrink(size_t shrink_bytes) {
1754 verify_region_sets_optional(); 1743 verify_region_sets_optional();
3577 3566
3578 { 3567 {
3579 size_t expand_bytes = g1_policy()->expansion_amount(); 3568 size_t expand_bytes = g1_policy()->expansion_amount();
3580 if (expand_bytes > 0) { 3569 if (expand_bytes > 0) {
3581 size_t bytes_before = capacity(); 3570 size_t bytes_before = capacity();
3571 // No need for an ergo verbose message here,
3572 // expansion_amount() does this when it returns a value > 0.
3582 if (!expand(expand_bytes)) { 3573 if (!expand(expand_bytes)) {
3583 // We failed to expand the heap so let's verify that 3574 // We failed to expand the heap so let's verify that
3584 // committed/uncommitted amount match the backing store 3575 // committed/uncommitted amount match the backing store
3585 assert(capacity() == _g1_storage.committed_size(), "committed size mismatch"); 3576 assert(capacity() == _g1_storage.committed_size(), "committed size mismatch");
3586 assert(max_capacity() == _g1_storage.reserved_size(), "reserved size mismatch"); 3577 assert(max_capacity() == _g1_storage.reserved_size(), "reserved size mismatch");
3730 G1IsAliveClosure(G1CollectedHeap* g1) : _g1(g1) {} 3721 G1IsAliveClosure(G1CollectedHeap* g1) : _g1(g1) {}
3731 void do_object(oop p) { assert(false, "Do not call."); } 3722 void do_object(oop p) { assert(false, "Do not call."); }
3732 bool do_object_b(oop p) { 3723 bool do_object_b(oop p) {
3733 // It is reachable if it is outside the collection set, or is inside 3724 // It is reachable if it is outside the collection set, or is inside
3734 // and forwarded. 3725 // and forwarded.
3735
3736 #ifdef G1_DEBUG
3737 gclog_or_tty->print_cr("is alive "PTR_FORMAT" in CS %d forwarded %d overall %d",
3738 (void*) p, _g1->obj_in_cs(p), p->is_forwarded(),
3739 !_g1->obj_in_cs(p) || p->is_forwarded());
3740 #endif // G1_DEBUG
3741
3742 return !_g1->obj_in_cs(p) || p->is_forwarded(); 3726 return !_g1->obj_in_cs(p) || p->is_forwarded();
3743 } 3727 }
3744 }; 3728 };
3745 3729
3746 class G1KeepAliveClosure: public OopClosure { 3730 class G1KeepAliveClosure: public OopClosure {
3748 public: 3732 public:
3749 G1KeepAliveClosure(G1CollectedHeap* g1) : _g1(g1) {} 3733 G1KeepAliveClosure(G1CollectedHeap* g1) : _g1(g1) {}
3750 void do_oop(narrowOop* p) { guarantee(false, "Not needed"); } 3734 void do_oop(narrowOop* p) { guarantee(false, "Not needed"); }
3751 void do_oop( oop* p) { 3735 void do_oop( oop* p) {
3752 oop obj = *p; 3736 oop obj = *p;
3753 #ifdef G1_DEBUG
3754 if (PrintGC && Verbose) {
3755 gclog_or_tty->print_cr("keep alive *"PTR_FORMAT" = "PTR_FORMAT" "PTR_FORMAT,
3756 p, (void*) obj, (void*) *p);
3757 }
3758 #endif // G1_DEBUG
3759
3760 if (_g1->obj_in_cs(obj)) { 3737 if (_g1->obj_in_cs(obj)) {
3761 assert( obj->is_forwarded(), "invariant" ); 3738 assert( obj->is_forwarded(), "invariant" );
3762 *p = obj->forwardee(); 3739 *p = obj->forwardee();
3763 #ifdef G1_DEBUG
3764 gclog_or_tty->print_cr(" in CSet: moved "PTR_FORMAT" -> "PTR_FORMAT,
3765 (void*) obj, (void*) *p);
3766 #endif // G1_DEBUG
3767 } 3740 }
3768 } 3741 }
3769 }; 3742 };
3770 3743
3771 class UpdateRSetDeferred : public OopsInHeapRegionClosure { 3744 class UpdateRSetDeferred : public OopsInHeapRegionClosure {