Mercurial > hg > graal-jvmci-8
comparison src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @ 9072:8617e38bb4cb
8008508: CMS does not correctly reduce heap size after a Full GC
Reviewed-by: johnc, ysr
author | jmasa |
---|---|
date | Mon, 11 Feb 2013 10:31:56 -0800 |
parents | 79af1312fc2c |
children | 7b835924c31c |
comparison
equal
deleted
inserted
replaced
9071:68fe50d4f1d5 | 9072:8617e38bb4cb |
---|---|
46 #include "memory/genMarkSweep.hpp" | 46 #include "memory/genMarkSweep.hpp" |
47 #include "memory/genOopClosures.inline.hpp" | 47 #include "memory/genOopClosures.inline.hpp" |
48 #include "memory/iterator.hpp" | 48 #include "memory/iterator.hpp" |
49 #include "memory/referencePolicy.hpp" | 49 #include "memory/referencePolicy.hpp" |
50 #include "memory/resourceArea.hpp" | 50 #include "memory/resourceArea.hpp" |
51 #include "memory/tenuredGeneration.hpp" | |
51 #include "oops/oop.inline.hpp" | 52 #include "oops/oop.inline.hpp" |
52 #include "prims/jvmtiExport.hpp" | 53 #include "prims/jvmtiExport.hpp" |
53 #include "runtime/globals_extension.hpp" | 54 #include "runtime/globals_extension.hpp" |
54 #include "runtime/handles.inline.hpp" | 55 #include "runtime/handles.inline.hpp" |
55 #include "runtime/java.hpp" | 56 #include "runtime/java.hpp" |
914 clear_incremental_collection_failed(); | 915 clear_incremental_collection_failed(); |
915 grow_to_reserved(); | 916 grow_to_reserved(); |
916 return; | 917 return; |
917 } | 918 } |
918 | 919 |
919 size_t expand_bytes = 0; | 920 // Compute some numbers about the state of the heap. |
921 const size_t used_after_gc = used(); | |
922 const size_t capacity_after_gc = capacity(); | |
923 | |
924 CardGeneration::compute_new_size(); | |
925 | |
926 // Reset again after a possible resizing | |
927 cmsSpace()->reset_after_compaction(); | |
928 | |
929 assert(used() == used_after_gc && used_after_gc <= capacity(), | |
930 err_msg("used: " SIZE_FORMAT " used_after_gc: " SIZE_FORMAT | |
931 " capacity: " SIZE_FORMAT, used(), used_after_gc, capacity())); | |
932 } | |
933 | |
934 void ConcurrentMarkSweepGeneration::compute_new_size_free_list() { | |
935 assert_locked_or_safepoint(Heap_lock); | |
936 | |
937 // If incremental collection failed, we just want to expand | |
938 // to the limit. | |
939 if (incremental_collection_failed()) { | |
940 clear_incremental_collection_failed(); | |
941 grow_to_reserved(); | |
942 return; | |
943 } | |
944 | |
920 double free_percentage = ((double) free()) / capacity(); | 945 double free_percentage = ((double) free()) / capacity(); |
921 double desired_free_percentage = (double) MinHeapFreeRatio / 100; | 946 double desired_free_percentage = (double) MinHeapFreeRatio / 100; |
922 double maximum_free_percentage = (double) MaxHeapFreeRatio / 100; | 947 double maximum_free_percentage = (double) MaxHeapFreeRatio / 100; |
923 | 948 |
924 // compute expansion delta needed for reaching desired free percentage | 949 // compute expansion delta needed for reaching desired free percentage |
925 if (free_percentage < desired_free_percentage) { | 950 if (free_percentage < desired_free_percentage) { |
926 size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage)); | 951 size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage)); |
927 assert(desired_capacity >= capacity(), "invalid expansion size"); | 952 assert(desired_capacity >= capacity(), "invalid expansion size"); |
928 expand_bytes = MAX2(desired_capacity - capacity(), MinHeapDeltaBytes); | 953 size_t expand_bytes = MAX2(desired_capacity - capacity(), MinHeapDeltaBytes); |
929 } | |
930 if (expand_bytes > 0) { | |
931 if (PrintGCDetails && Verbose) { | 954 if (PrintGCDetails && Verbose) { |
932 size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage)); | 955 size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage)); |
933 gclog_or_tty->print_cr("\nFrom compute_new_size: "); | 956 gclog_or_tty->print_cr("\nFrom compute_new_size: "); |
934 gclog_or_tty->print_cr(" Free fraction %f", free_percentage); | 957 gclog_or_tty->print_cr(" Free fraction %f", free_percentage); |
935 gclog_or_tty->print_cr(" Desired free fraction %f", | 958 gclog_or_tty->print_cr(" Desired free fraction %f", |
958 // safe if expansion fails | 981 // safe if expansion fails |
959 expand(expand_bytes, 0, CMSExpansionCause::_satisfy_free_ratio); | 982 expand(expand_bytes, 0, CMSExpansionCause::_satisfy_free_ratio); |
960 if (PrintGCDetails && Verbose) { | 983 if (PrintGCDetails && Verbose) { |
961 gclog_or_tty->print_cr(" Expanded free fraction %f", | 984 gclog_or_tty->print_cr(" Expanded free fraction %f", |
962 ((double) free()) / capacity()); | 985 ((double) free()) / capacity()); |
986 } | |
987 } else { | |
988 size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage)); | |
989 assert(desired_capacity <= capacity(), "invalid expansion size"); | |
990 size_t shrink_bytes = capacity() - desired_capacity; | |
991 // Don't shrink unless the delta is greater than the minimum shrink we want | |
992 if (shrink_bytes >= MinHeapDeltaBytes) { | |
993 shrink_free_list_by(shrink_bytes); | |
963 } | 994 } |
964 } | 995 } |
965 } | 996 } |
966 | 997 |
967 Mutex* ConcurrentMarkSweepGeneration::freelistLock() const { | 998 Mutex* ConcurrentMarkSweepGeneration::freelistLock() const { |
1870 // two generations. | 1901 // two generations. |
1871 void CMSCollector::compute_new_size() { | 1902 void CMSCollector::compute_new_size() { |
1872 assert_locked_or_safepoint(Heap_lock); | 1903 assert_locked_or_safepoint(Heap_lock); |
1873 FreelistLocker z(this); | 1904 FreelistLocker z(this); |
1874 MetaspaceGC::compute_new_size(); | 1905 MetaspaceGC::compute_new_size(); |
1875 _cmsGen->compute_new_size(); | 1906 _cmsGen->compute_new_size_free_list(); |
1876 } | 1907 } |
1877 | 1908 |
1878 // A work method used by foreground collection to determine | 1909 // A work method used by foreground collection to determine |
1879 // what type of collection (compacting or not, continuing or fresh) | 1910 // what type of collection (compacting or not, continuing or fresh) |
1880 // it should do. | 1911 // it should do. |
2599 stats().record_gc0_begin(); | 2630 stats().record_gc0_begin(); |
2600 } | 2631 } |
2601 } | 2632 } |
2602 | 2633 |
2603 void ConcurrentMarkSweepGeneration::gc_prologue(bool full) { | 2634 void ConcurrentMarkSweepGeneration::gc_prologue(bool full) { |
2635 | |
2636 _capacity_at_prologue = capacity(); | |
2637 _used_at_prologue = used(); | |
2638 | |
2604 // Delegate to CMScollector which knows how to coordinate between | 2639 // Delegate to CMScollector which knows how to coordinate between |
2605 // this and any other CMS generations that it is responsible for | 2640 // this and any other CMS generations that it is responsible for |
2606 // collecting. | 2641 // collecting. |
2607 collector()->gc_prologue(full); | 2642 collector()->gc_prologue(full); |
2608 } | 2643 } |
3298 } | 3333 } |
3299 } | 3334 } |
3300 } | 3335 } |
3301 | 3336 |
3302 | 3337 |
3338 void ConcurrentMarkSweepGeneration::shrink_by(size_t bytes) { | |
3339 assert_locked_or_safepoint(ExpandHeap_lock); | |
3340 // Shrink committed space | |
3341 _virtual_space.shrink_by(bytes); | |
3342 // Shrink space; this also shrinks the space's BOT | |
3343 _cmsSpace->set_end((HeapWord*) _virtual_space.high()); | |
3344 size_t new_word_size = heap_word_size(_cmsSpace->capacity()); | |
3345 // Shrink the shared block offset array | |
3346 _bts->resize(new_word_size); | |
3347 MemRegion mr(_cmsSpace->bottom(), new_word_size); | |
3348 // Shrink the card table | |
3349 Universe::heap()->barrier_set()->resize_covered_region(mr); | |
3350 | |
3351 if (Verbose && PrintGC) { | |
3352 size_t new_mem_size = _virtual_space.committed_size(); | |
3353 size_t old_mem_size = new_mem_size + bytes; | |
3354 gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K to " SIZE_FORMAT "K", | |
3355 name(), old_mem_size/K, new_mem_size/K); | |
3356 } | |
3357 } | |
3303 | 3358 |
3304 void ConcurrentMarkSweepGeneration::shrink(size_t bytes) { | 3359 void ConcurrentMarkSweepGeneration::shrink(size_t bytes) { |
3305 assert_locked_or_safepoint(Heap_lock); | 3360 assert_locked_or_safepoint(Heap_lock); |
3306 size_t size = ReservedSpace::page_align_size_down(bytes); | 3361 size_t size = ReservedSpace::page_align_size_down(bytes); |
3307 if (size > 0) { | 3362 if (size > 0) { |
3349 DEBUG_ONLY(if (!success) warning("grow to reserved failed");) | 3404 DEBUG_ONLY(if (!success) warning("grow to reserved failed");) |
3350 } | 3405 } |
3351 return success; | 3406 return success; |
3352 } | 3407 } |
3353 | 3408 |
3354 void ConcurrentMarkSweepGeneration::shrink_by(size_t bytes) { | 3409 void ConcurrentMarkSweepGeneration::shrink_free_list_by(size_t bytes) { |
3355 assert_locked_or_safepoint(Heap_lock); | 3410 assert_locked_or_safepoint(Heap_lock); |
3356 assert_lock_strong(freelistLock()); | 3411 assert_lock_strong(freelistLock()); |
3357 // XXX Fix when compaction is implemented. | 3412 // XXX Fix when compaction is implemented. |
3358 warning("Shrinking of CMS not yet implemented"); | 3413 warning("Shrinking of CMS not yet implemented"); |
3359 return; | 3414 return; |
9072 "Wrong gc statistics type"); | 9127 "Wrong gc statistics type"); |
9073 counters->update_counters(gc_stats_l); | 9128 counters->update_counters(gc_stats_l); |
9074 } | 9129 } |
9075 } | 9130 } |
9076 | 9131 |
9077 // The desired expansion delta is computed so that: | |
9078 // . desired free percentage or greater is used | |
9079 void ASConcurrentMarkSweepGeneration::compute_new_size() { | |
9080 assert_locked_or_safepoint(Heap_lock); | |
9081 | |
9082 GenCollectedHeap* gch = (GenCollectedHeap*) GenCollectedHeap::heap(); | |
9083 | |
9084 // If incremental collection failed, we just want to expand | |
9085 // to the limit. | |
9086 if (incremental_collection_failed()) { | |
9087 clear_incremental_collection_failed(); | |
9088 grow_to_reserved(); | |
9089 return; | |
9090 } | |
9091 | |
9092 assert(UseAdaptiveSizePolicy, "Should be using adaptive sizing"); | |
9093 | |
9094 assert(gch->kind() == CollectedHeap::GenCollectedHeap, | |
9095 "Wrong type of heap"); | |
9096 int prev_level = level() - 1; | |
9097 assert(prev_level >= 0, "The cms generation is the lowest generation"); | |
9098 Generation* prev_gen = gch->get_gen(prev_level); | |
9099 assert(prev_gen->kind() == Generation::ASParNew, | |
9100 "Wrong type of young generation"); | |
9101 ParNewGeneration* younger_gen = (ParNewGeneration*) prev_gen; | |
9102 size_t cur_eden = younger_gen->eden()->capacity(); | |
9103 CMSAdaptiveSizePolicy* size_policy = cms_size_policy(); | |
9104 size_t cur_promo = free(); | |
9105 size_policy->compute_tenured_generation_free_space(cur_promo, | |
9106 max_available(), | |
9107 cur_eden); | |
9108 resize(cur_promo, size_policy->promo_size()); | |
9109 | |
9110 // Record the new size of the space in the cms generation | |
9111 // that is available for promotions. This is temporary. | |
9112 // It should be the desired promo size. | |
9113 size_policy->avg_cms_promo()->sample(free()); | |
9114 size_policy->avg_old_live()->sample(used()); | |
9115 | |
9116 if (UsePerfData) { | |
9117 CMSGCAdaptivePolicyCounters* counters = gc_adaptive_policy_counters(); | |
9118 counters->update_cms_capacity_counter(capacity()); | |
9119 } | |
9120 } | |
9121 | |
9122 void ASConcurrentMarkSweepGeneration::shrink_by(size_t desired_bytes) { | 9132 void ASConcurrentMarkSweepGeneration::shrink_by(size_t desired_bytes) { |
9123 assert_locked_or_safepoint(Heap_lock); | 9133 assert_locked_or_safepoint(Heap_lock); |
9124 assert_lock_strong(freelistLock()); | 9134 assert_lock_strong(freelistLock()); |
9125 HeapWord* old_end = _cmsSpace->end(); | 9135 HeapWord* old_end = _cmsSpace->end(); |
9126 HeapWord* unallocated_start = _cmsSpace->unallocated_block(); | 9136 HeapWord* unallocated_start = _cmsSpace->unallocated_block(); |