diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index dea030fa8cce6d687766e2a67cb711bc33ed279d..1a0097d09b7353164a38b6a1737123ef7a1686cf 100644 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -737,7 +737,7 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen, // Support for parallelizing survivor space rescan if ((CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) || CMSParallelInitialMarkEnabled) { const size_t max_plab_samples = - ((DefNewGeneration*)_young_gen)->max_survivor_size()/MinTLABSize; + ((DefNewGeneration*)_young_gen)->max_survivor_size() / plab_sample_minimum_size(); _survivor_plab_array = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads, mtGC); _survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples, mtGC); @@ -795,6 +795,12 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen, _inter_sweep_timer.start(); // start of time } +size_t CMSCollector::plab_sample_minimum_size() { + // The default value of MinTLABSize is 2k, but there is + // no way to get the default value if the flag has been overridden. + return MAX2(ThreadLocalAllocBuffer::min_size() * HeapWordSize, 2 * K); +} + const char* ConcurrentMarkSweepGeneration::name() const { return "concurrent mark-sweep generation"; } diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp index 2c87671dfe22f2774f3094d79f51388748246da5..7cd4153ff3834d6c493b74e67461608d046ec4d1 100644 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp @@ -763,6 +763,10 @@ class CMSCollector: public CHeapObj { size_t* _cursor; ChunkArray* _survivor_plab_array; + // A bounded minimum size of PLABs, should not return too small values since + // this will affect the size of the data structures used for parallel young gen rescan + size_t plab_sample_minimum_size(); + // Support for marking stack overflow handling bool take_from_overflow_list(size_t num, CMSMarkStack* to_stack); bool par_take_from_overflow_list(size_t num, diff --git a/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp index aac3e9815cc02adb68a1f98e5d278c5388cd841a..c02822f0931131eec5bf2c33128b1b1b0993e896 100644 --- a/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp +++ b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp @@ -62,7 +62,8 @@ public: ParGCAllocBuffer(size_t word_sz); static const size_t min_size() { - return ThreadLocalAllocBuffer::min_size(); + // Make sure that we return something that is larger than AlignmentReserve + return align_object_size(MAX2(MinTLABSize / HeapWordSize, (uintx)oopDesc::header_size())) + AlignmentReserve; } static const size_t max_size() { diff --git a/src/share/vm/memory/threadLocalAllocBuffer.cpp b/src/share/vm/memory/threadLocalAllocBuffer.cpp index b59cfd80d393b12262ab82418aa5912a4efda3bc..06033439c5a8b0d93d02e92cc7dba71b67beb54a 100644 --- a/src/share/vm/memory/threadLocalAllocBuffer.cpp +++ b/src/share/vm/memory/threadLocalAllocBuffer.cpp @@ -235,22 +235,19 @@ void ThreadLocalAllocBuffer::startup_initialization() { } size_t ThreadLocalAllocBuffer::initial_desired_size() { - size_t init_sz; + size_t init_sz = 0; if (TLABSize > 0) { - init_sz = MIN2(TLABSize / HeapWordSize, max_size()); - } else if (global_stats() == NULL) { - // Startup issue - main thread initialized before heap initialized. - init_sz = min_size(); - } else { + init_sz = TLABSize / HeapWordSize; + } else if (global_stats() != NULL) { // Initial size is a function of the average number of allocating threads. unsigned nof_threads = global_stats()->allocating_threads_avg(); init_sz = (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize) / (nof_threads * target_refills()); init_sz = align_object_size(init_sz); - init_sz = MIN2(MAX2(init_sz, min_size()), max_size()); } + init_sz = MIN2(MAX2(init_sz, min_size()), max_size()); return init_sz; } diff --git a/src/share/vm/memory/threadLocalAllocBuffer.hpp b/src/share/vm/memory/threadLocalAllocBuffer.hpp index e0dc61a73f6236fce3345a7fbcd28102a79f7474..07308ff7ed33b7119ca2d63595b171127cd7e209 100644 --- a/src/share/vm/memory/threadLocalAllocBuffer.hpp +++ b/src/share/vm/memory/threadLocalAllocBuffer.hpp @@ -105,7 +105,7 @@ public: // do nothing. tlabs must be inited by initialize() calls } - static const size_t min_size() { return align_object_size(MinTLABSize / HeapWordSize); } + static const size_t min_size() { return align_object_size(MinTLABSize / HeapWordSize) + alignment_reserve(); } static const size_t max_size() { assert(_max_size != 0, "max_size not set up"); return _max_size; } static void set_max_size(size_t max_size) { _max_size = max_size; }