--- old/src/share/vm/memory/collectorPolicy.cpp 2013-03-18 10:49:06.141736140 +0100 +++ new/src/share/vm/memory/collectorPolicy.cpp 2013-03-18 10:49:05.921736145 +0100 @@ -48,6 +48,10 @@ // CollectorPolicy methods. void CollectorPolicy::initialize_flags() { + if (MaxHeapSize < InitialHeapSize) { + vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified"); + } + if (MetaspaceSize > MaxMetaspaceSize) { MaxMetaspaceSize = MetaspaceSize; } @@ -233,9 +237,6 @@ GenCollectorPolicy::initialize_flags(); OldSize = align_size_down(OldSize, min_alignment()); - if (NewSize + OldSize > MaxHeapSize) { - MaxHeapSize = NewSize + OldSize; - } if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(NewSize)) { // NewRatio will be used later to set the young generation size so we use @@ -250,6 +251,27 @@ } MaxHeapSize = align_size_up(MaxHeapSize, max_alignment()); + // adjust max heap size if necessary + if (NewSize + OldSize > MaxHeapSize) { + if (FLAG_IS_CMDLINE(MaxHeapSize)) { + // somebody set a maximum heap size with the intention that we should not + // exceed it. Adjust New/OldSize as necessary. + uintx calculated_size = NewSize + OldSize; + double shrink_factor = (double) MaxHeapSize / calculated_size; + // align + NewSize = align_size_down((uintx) (NewSize * shrink_factor), min_alignment()); + // OldSize is already aligned because above we aligned MaxHeapSize to + // max_alignment(), and we just made sure that NewSize is aligned to + // min_alignment(). In initialize_flags() we verified that max_alignment() + // is a multiple of min_alignment(). + OldSize = MaxHeapSize - NewSize; + } else { + MaxHeapSize = NewSize + OldSize; + } + } + // need to do this again + MaxHeapSize = align_size_up(MaxHeapSize, max_alignment()); + always_do_update_barrier = UseConcMarkSweepGC; // Check validity of heap flags