예제 #1
0
void GenCollectorPolicy::initialize_flags() {
  // All sizes must be multiples of the generation granularity.
  set_min_alignment((uintx) Generation::GenGrain);
  set_max_alignment(compute_max_alignment());

  CollectorPolicy::initialize_flags();

  // All generational heaps have a youngest gen; handle those flags here.

  // Adjust max size parameters
  if (NewSize > MaxNewSize) {
    MaxNewSize = NewSize;
  }
  NewSize = align_size_down(NewSize, min_alignment());
  MaxNewSize = align_size_down(MaxNewSize, min_alignment());

  // Check validity of heap flags
  assert(NewSize     % min_alignment() == 0, "eden space alignment");
  assert(MaxNewSize  % min_alignment() == 0, "survivor space alignment");

  if (NewSize < 3*min_alignment()) {
     // make sure there room for eden and two survivor spaces
    vm_exit_during_initialization("Too small new size specified");
  }
  if (SurvivorRatio < 1 || NewRatio < 1) {
    vm_exit_during_initialization("Invalid heap ratio specified");
  }
}
예제 #2
0
size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) {
  size_t x = base_size / (NewRatio+1);
  size_t new_gen_size = x > min_alignment() ?
                     align_size_down(x, min_alignment()) :
                     min_alignment();
  return new_gen_size;
}
예제 #3
0
// Call this method during the sizing of the gen1 to make
// adjustments to gen0 because of gen1 sizing policy.  gen0 initially has
// the most freedom in sizing because it is done before the
// policy for gen1 is applied.  Once gen1 policies have been applied,
// there may be conflicts in the shape of the heap and this method
// is used to make the needed adjustments.  The application of the
// policies could be more sophisticated (iterative for example) but
// keeping it simple also seems a worthwhile goal.
bool TwoGenerationCollectorPolicy::adjust_gen0_sizes(size_t* gen0_size_ptr,
                                                     size_t* gen1_size_ptr,
                                                     size_t heap_size,
                                                     size_t min_gen0_size) {
  bool result = false;
  if ((*gen1_size_ptr + *gen0_size_ptr) > heap_size) {
    if (((*gen0_size_ptr + OldSize) > heap_size) &&
       (heap_size - min_gen0_size) >= min_alignment()) {
      // Adjust gen0 down to accomodate OldSize
      *gen0_size_ptr = heap_size - min_gen0_size;
      *gen0_size_ptr =
        MAX2((uintx)align_size_down(*gen0_size_ptr, min_alignment()),
             min_alignment());
      assert(*gen0_size_ptr > 0, "Min gen0 is too large");
      result = true;
    } else {
      *gen1_size_ptr = heap_size - *gen0_size_ptr;
      *gen1_size_ptr =
        MAX2((uintx)align_size_down(*gen1_size_ptr, min_alignment()),
                       min_alignment());
    }
  }

  return result;
}
예제 #4
0
void TwoGenerationCollectorPolicy::initialize_size_info() {
  // User inputs from -mx and ms are aligned
  MaxNewSize = align_size_down(MaxNewSize, min_alignment());
  uintx initial_heap_size = align_size_up(Arguments::initial_heap_size(), min_alignment());
  uintx max_heap_size     = align_size_up(MaxHeapSize, max_alignment());

#ifndef COMPILER2    // Don't degrade server performance for footprint
  if (FLAG_IS_DEFAULT(UseMPSS) && max_heap_size < LargePageHeapSizeThreshold) {
    // No need for large granularity pages w/small heaps.
    UseMPSS = false;
  }
#endif

  // Check validity of heap parameters from launcher
  if (initial_heap_size == 0) {
    initial_heap_size = NewSize + OldSize;
  } else {
    Universe::check_alignment(initial_heap_size, min_alignment(), "initial heap");
  }

  // Check heap parameter properties
  if (initial_heap_size < M) {
    vm_exit_during_initialization("Too small initial heap");
  }
  if (initial_heap_size <= NewSize) {
     // make sure there is at least some room in old space
    vm_exit_during_initialization("Too small initial heap for new size specified");
  }
  if (max_heap_size < initial_heap_size) {
    vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified");
  }

  // Minimum sizes of the generations may be different than
  // the initial sizes.
  _min_gen0_size = NewSize;
  _min_gen1_size = OldSize;

  // Parameters are valid, compute area sizes.
  size_t max_new_size = align_size_down(max_heap_size / (NewRatio+1),
					min_alignment());
  max_new_size = MIN2(MAX2(max_new_size, _min_gen0_size), MaxNewSize);

  size_t desired_new_size = align_size_down(initial_heap_size / (NewRatio+1),
					    min_alignment());

  size_t new_size = MIN2(MAX2(desired_new_size, _min_gen0_size), max_new_size);
  // I'm putting this in to make sure the compilation of the code above is
  // correct.  At times, it hasn't been. -dld 04/00.
  guarantee(new_size <= max_new_size &&
	    new_size <= MAX2(desired_new_size, _min_gen0_size),
	    "Or what gives");


  _initial_gen0_size = new_size;
  _max_gen0_size = max_new_size;

  _initial_gen1_size = initial_heap_size - new_size;
  _max_gen1_size = max_heap_size - max_new_size;
}
예제 #5
0
void TwoGenerationCollectorPolicy::initialize_flags() {
  GenCollectorPolicy::initialize_flags();

  OldSize = align_size_down(OldSize, min_alignment());
  if (NewSize + OldSize > MaxHeapSize) {
    MaxHeapSize = NewSize + OldSize;
  }
  MaxHeapSize = align_size_up(MaxHeapSize, max_alignment());

  always_do_update_barrier = UseConcMarkSweepGC;

  // Check validity of heap flags
  assert(OldSize     % min_alignment() == 0, "old space alignment");
  assert(MaxHeapSize % max_alignment() == 0, "maximum heap alignment");
}
예제 #6
0
void CollectorPolicy::initialize_size_info() {
  // User inputs from -mx and ms are aligned
  set_initial_heap_byte_size(InitialHeapSize);
  if (initial_heap_byte_size() == 0) {
    set_initial_heap_byte_size(NewSize + OldSize);
  }
  set_initial_heap_byte_size(align_size_up(_initial_heap_byte_size,
                                           min_alignment()));

  set_min_heap_byte_size(Arguments::min_heap_size());
  if (min_heap_byte_size() == 0) {
    set_min_heap_byte_size(NewSize + OldSize);
  }
  set_min_heap_byte_size(align_size_up(_min_heap_byte_size,
                                       min_alignment()));

  set_max_heap_byte_size(align_size_up(MaxHeapSize, max_alignment()));

  // Check heap parameter properties
  if (initial_heap_byte_size() < M) {
    vm_exit_during_initialization("Too small initial heap");
  }
  // Check heap parameter properties
  if (min_heap_byte_size() < M) {
    vm_exit_during_initialization("Too small minimum heap");
  }
  if (initial_heap_byte_size() <= NewSize) {
     // make sure there is at least some room in old space
    vm_exit_during_initialization("Too small initial heap for new size specified");
  }
  if (max_heap_byte_size() < min_heap_byte_size()) {
    vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified");
  }
  if (initial_heap_byte_size() < min_heap_byte_size()) {
    vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified");
  }
  if (max_heap_byte_size() < initial_heap_byte_size()) {
    vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified");
  }

  if (PrintGCDetails && Verbose) {
    gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT "  Initial heap "
      SIZE_FORMAT "  Maximum heap " SIZE_FORMAT,
      min_heap_byte_size(), initial_heap_byte_size(), max_heap_byte_size());
  }
}
예제 #7
0
void CollectorPolicy::initialize_flags() {
  if (PermSize > MaxPermSize) {
    MaxPermSize = PermSize;
  }
  PermSize = MAX2(min_alignment(), align_size_down_(PermSize, min_alignment()));
  MaxPermSize = align_size_up(MaxPermSize, max_alignment());

  MinPermHeapExpansion = MAX2(min_alignment(), align_size_down_(MinPermHeapExpansion, min_alignment()));
  MaxPermHeapExpansion = MAX2(min_alignment(), align_size_down_(MaxPermHeapExpansion, min_alignment()));

  MinHeapDeltaBytes = align_size_up(MinHeapDeltaBytes, min_alignment());

  SharedReadOnlySize = align_size_up(SharedReadOnlySize, max_alignment());
  SharedReadWriteSize = align_size_up(SharedReadWriteSize, max_alignment());
  SharedMiscDataSize = align_size_up(SharedMiscDataSize, max_alignment());

  assert(PermSize    % min_alignment() == 0, "permanent space alignment");
  assert(MaxPermSize % max_alignment() == 0, "maximum permanent space alignment");
  assert(SharedReadOnlySize % max_alignment() == 0, "read-only space alignment");
  assert(SharedReadWriteSize % max_alignment() == 0, "read-write space alignment");
  assert(SharedMiscDataSize % max_alignment() == 0, "misc-data space alignment");
  if (PermSize < M) {
    vm_exit_during_initialization("Too small initial permanent heap");
  }
}
예제 #8
0
/**
 * 检查/调整永久代的内存配置
 */
void CollectorPolicy::initialize_flags() {
  if (PermSize > MaxPermSize) {
    MaxPermSize = PermSize;
  }

  PermSize = MAX2(min_alignment(), align_size_down_(PermSize, min_alignment()));
  // Don't increase Perm size limit above specified.
  MaxPermSize = align_size_down(MaxPermSize, max_alignment());
  if (PermSize > MaxPermSize) {
    PermSize = MaxPermSize;
  }

  MinPermHeapExpansion = MAX2(min_alignment(), align_size_down_(MinPermHeapExpansion, min_alignment()));
  MaxPermHeapExpansion = MAX2(min_alignment(), align_size_down_(MaxPermHeapExpansion, min_alignment()));

  MinHeapDeltaBytes = align_size_up(MinHeapDeltaBytes, min_alignment());

  SharedReadOnlySize = align_size_up(SharedReadOnlySize, max_alignment());
  SharedReadWriteSize = align_size_up(SharedReadWriteSize, max_alignment());
  SharedMiscDataSize = align_size_up(SharedMiscDataSize, max_alignment());

  assert(PermSize    % min_alignment() == 0, "permanent space alignment");
  assert(MaxPermSize % max_alignment() == 0, "maximum permanent space alignment");
  assert(SharedReadOnlySize % max_alignment() == 0, "read-only space alignment");
  assert(SharedReadWriteSize % max_alignment() == 0, "read-write space alignment");
  assert(SharedMiscDataSize % max_alignment() == 0, "misc-data space alignment");
  if (PermSize < M) {
	printf("%s[%d] [tid: %lu]: 永久代配置太小: PermSize(%lu) < M(%lu).\n", __FILE__, __LINE__, pthread_self(), PermSize, M);
    vm_exit_during_initialization("Too small initial permanent heap");
  }

}
예제 #9
0
void CollectorPolicy::initialize_flags() {
  assert(max_alignment() >= min_alignment(),
      err_msg("max_alignment: " SIZE_FORMAT " less than min_alignment: " SIZE_FORMAT,
          max_alignment(), min_alignment()));
  assert(max_alignment() % min_alignment() == 0,
      err_msg("max_alignment: " SIZE_FORMAT " not aligned by min_alignment: " SIZE_FORMAT,
          max_alignment(), min_alignment()));

  if (PermSize > MaxPermSize) {
    MaxPermSize = PermSize;
  }
  PermSize = MAX2(min_alignment(), align_size_down_(PermSize, min_alignment()));
  // Don't increase Perm size limit above specified.
  MaxPermSize = align_size_down(MaxPermSize, max_alignment());
  if (PermSize > MaxPermSize) {
    PermSize = MaxPermSize;
  }

  MinPermHeapExpansion = MAX2(min_alignment(), align_size_down_(MinPermHeapExpansion, min_alignment()));
  MaxPermHeapExpansion = MAX2(min_alignment(), align_size_down_(MaxPermHeapExpansion, min_alignment()));

  MinHeapDeltaBytes = align_size_up(MinHeapDeltaBytes, min_alignment());

  SharedReadOnlySize = align_size_up(SharedReadOnlySize, max_alignment());
  SharedReadWriteSize = align_size_up(SharedReadWriteSize, max_alignment());
  SharedMiscDataSize = align_size_up(SharedMiscDataSize, max_alignment());

  assert(PermSize    % min_alignment() == 0, "permanent space alignment");
  assert(MaxPermSize % max_alignment() == 0, "maximum permanent space alignment");
  assert(SharedReadOnlySize % max_alignment() == 0, "read-only space alignment");
  assert(SharedReadWriteSize % max_alignment() == 0, "read-write space alignment");
  assert(SharedMiscDataSize % max_alignment() == 0, "misc-data space alignment");
  if (PermSize < M) {
    vm_exit_during_initialization("Too small initial permanent heap");
  }
}
예제 #10
0
void TwoGenerationCollectorPolicy::initialize_size_info() {
  GenCollectorPolicy::initialize_size_info();

  // At this point the minimum, initial and maximum sizes
  // of the overall heap and of gen0 have been determined.
  // The maximum gen1 size can be determined from the maximum gen0
  // and maximum heap size since not explicit flags exits
  // for setting the gen1 maximum.
  _max_gen1_size = max_heap_byte_size() - _max_gen0_size;
  _max_gen1_size =
    MAX2((size_t)align_size_down(_max_gen1_size, min_alignment()),
         min_alignment());
  // If no explicit command line flag has been set for the
  // gen1 size, use what is left for gen1.
  if (FLAG_IS_DEFAULT(OldSize) || FLAG_IS_ERGO(OldSize)) {
    // The user has not specified any value or ergonomics
    // has chosen a value (which may or may not be consistent
    // with the overall heap size).  In either case make
    // the minimum, maximum and initial sizes consistent
    // with the gen0 sizes and the overall heap sizes.
    assert(min_heap_byte_size() > _min_gen0_size,
      "gen0 has an unexpected minimum size");
    set_min_gen1_size(min_heap_byte_size() - min_gen0_size());
    set_min_gen1_size(
      MAX2((size_t)align_size_down(_min_gen1_size, min_alignment()),
           min_alignment()));
    set_initial_gen1_size(initial_heap_byte_size() - initial_gen0_size());
    set_initial_gen1_size(
      MAX2((size_t)align_size_down(_initial_gen1_size, min_alignment()),
           min_alignment()));

  } else {
    // It's been explicitly set on the command line.  Use the
    // OldSize and then determine the consequences.
    set_min_gen1_size(OldSize);
    set_initial_gen1_size(OldSize);

    // If the user has explicitly set an OldSize that is inconsistent
    // with other command line flags, issue a warning.
    // The generation minimums and the overall heap mimimum should
    // be within one heap alignment.
    if ((_min_gen1_size + _min_gen0_size + min_alignment()) <
           min_heap_byte_size()) {
      warning("Inconsistency between minimum heap size and minimum "
          "generation sizes: using minimum heap = " SIZE_FORMAT,
          min_heap_byte_size());
    }
    if ((OldSize > _max_gen1_size)) {
      warning("Inconsistency between maximum heap size and maximum "
          "generation sizes: using maximum heap = " SIZE_FORMAT
          " -XX:OldSize flag is being ignored",
          max_heap_byte_size());
  }
    // If there is an inconsistency between the OldSize and the minimum and/or
    // initial size of gen0, since OldSize was explicitly set, OldSize wins.
    if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size,
                          min_heap_byte_size(), OldSize)) {
      if (PrintGCDetails && Verbose) {
        gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT "  Initial gen0 "
              SIZE_FORMAT "  Maximum gen0 " SIZE_FORMAT,
              min_gen0_size(), initial_gen0_size(), max_gen0_size());
      }
    }
    // Initial size
    if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size,
                         initial_heap_byte_size(), OldSize)) {
      if (PrintGCDetails && Verbose) {
        gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT "  Initial gen0 "
          SIZE_FORMAT "  Maximum gen0 " SIZE_FORMAT,
          min_gen0_size(), initial_gen0_size(), max_gen0_size());
      }
    }
  }
  // Enforce the maximum gen1 size.
  set_min_gen1_size(MIN2(_min_gen1_size, _max_gen1_size));

  // Check that min gen1 <= initial gen1 <= max gen1
  set_initial_gen1_size(MAX2(_initial_gen1_size, _min_gen1_size));
  set_initial_gen1_size(MIN2(_initial_gen1_size, _max_gen1_size));

  if (PrintGCDetails && Verbose) {
    gclog_or_tty->print_cr("Minimum gen1 " SIZE_FORMAT "  Initial gen1 "
      SIZE_FORMAT "  Maximum gen1 " SIZE_FORMAT,
      min_gen1_size(), initial_gen1_size(), max_gen1_size());
  }
}
예제 #11
0
// Values set on the command line win over any ergonomically
// set command line parameters.
// Ergonomic choice of parameters are done before this
// method is called.  Values for command line parameters such as NewSize
// and MaxNewSize feed those ergonomic choices into this method.
// This method makes the final generation sizings consistent with
// themselves and with overall heap sizings.
// In the absence of explicitly set command line flags, policies
// such as the use of NewRatio are used to size the generation.
void GenCollectorPolicy::initialize_size_info() {
  CollectorPolicy::initialize_size_info();

  // min_alignment() is used for alignment within a generation.
  // There is additional alignment done down stream for some
  // collectors that sometimes causes unwanted rounding up of
  // generations sizes.

  // Determine maximum size of gen0

  size_t max_new_size = 0;
  if (FLAG_IS_CMDLINE(MaxNewSize)) {
    if (MaxNewSize < min_alignment()) {
      max_new_size = min_alignment();
    } else if (MaxNewSize >= max_heap_byte_size()) {
      max_new_size = align_size_down(max_heap_byte_size() - min_alignment(),
                                     min_alignment());
      warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or "
        "greater than the entire heap (" SIZE_FORMAT "k).  A "
        "new generation size of " SIZE_FORMAT "k will be used.",
        MaxNewSize/K, max_heap_byte_size()/K, max_new_size/K);
    } else {
      max_new_size = align_size_down(MaxNewSize, min_alignment());
    }

  // The case for FLAG_IS_ERGO(MaxNewSize) could be treated
  // specially at this point to just use an ergonomically set
  // MaxNewSize to set max_new_size.  For cases with small
  // heaps such a policy often did not work because the MaxNewSize
  // was larger than the entire heap.  The interpretation given
  // to ergonomically set flags is that the flags are set
  // by different collectors for their own special needs but
  // are not allowed to badly shape the heap.  This allows the
  // different collectors to decide what's best for themselves
  // without having to factor in the overall heap shape.  It
  // can be the case in the future that the collectors would
  // only make "wise" ergonomics choices and this policy could
  // just accept those choices.  The choices currently made are
  // not always "wise".
  } else {
    max_new_size = scale_by_NewRatio_aligned(max_heap_byte_size());
    // Bound the maximum size by NewSize below (since it historically
    // would have been NewSize and because the NewRatio calculation could
    // yield a size that is too small) and bound it by MaxNewSize above.
    // Ergonomics plays here by previously calculating the desired
    // NewSize and MaxNewSize.
    max_new_size = MIN2(MAX2(max_new_size, (size_t)NewSize), (size_t)MaxNewSize);
  }
  assert(max_new_size > 0, "All paths should set max_new_size");

  // Given the maximum gen0 size, determine the initial and
  // minimum sizes.

  if (max_heap_byte_size() == min_heap_byte_size()) {
    // The maximum and minimum heap sizes are the same so
    // the generations minimum and initial must be the
    // same as its maximum.
    set_min_gen0_size(max_new_size);
    set_initial_gen0_size(max_new_size);
    set_max_gen0_size(max_new_size);
  } else {
    size_t desired_new_size = 0;
    if (!FLAG_IS_DEFAULT(NewSize)) {
      // If NewSize is set ergonomically (for example by cms), it
      // would make sense to use it.  If it is used, also use it
      // to set the initial size.  Although there is no reason
      // the minimum size and the initial size have to be the same,
      // the current implementation gets into trouble during the calculation
      // of the tenured generation sizes if they are different.
      // Note that this makes the initial size and the minimum size
      // generally small compared to the NewRatio calculation.
      _min_gen0_size = NewSize;
      desired_new_size = NewSize;
      max_new_size = MAX2(max_new_size, (size_t) NewSize);
    } else {
      // For the case where NewSize is the default, use NewRatio
      // to size the minimum and initial generation sizes.
      // Use the default NewSize as the floor for these values.  If
      // NewRatio is overly large, the resulting sizes can be too
      // small.
      _min_gen0_size = MAX2(scale_by_NewRatio_aligned(min_heap_byte_size()),
                          (size_t) NewSize);
      desired_new_size =
        MAX2(scale_by_NewRatio_aligned(initial_heap_byte_size()),
             (size_t) NewSize);
    }

    assert(_min_gen0_size > 0, "Sanity check");
    set_initial_gen0_size(desired_new_size);
    set_max_gen0_size(max_new_size);

    // At this point the desirable initial and minimum sizes have been
    // determined without regard to the maximum sizes.

    // Bound the sizes by the corresponding overall heap sizes.
    set_min_gen0_size(
      bound_minus_alignment(_min_gen0_size, min_heap_byte_size()));
    set_initial_gen0_size(
      bound_minus_alignment(_initial_gen0_size, initial_heap_byte_size()));
    set_max_gen0_size(
      bound_minus_alignment(_max_gen0_size, max_heap_byte_size()));

    // At this point all three sizes have been checked against the
    // maximum sizes but have not been checked for consistency
    // among the three.

    // Final check min <= initial <= max
    set_min_gen0_size(MIN2(_min_gen0_size, _max_gen0_size));
    set_initial_gen0_size(
      MAX2(MIN2(_initial_gen0_size, _max_gen0_size), _min_gen0_size));
    set_min_gen0_size(MIN2(_min_gen0_size, _initial_gen0_size));
  }

  if (PrintGCDetails && Verbose) {
    gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT "  Initial gen0 "
      SIZE_FORMAT "  Maximum gen0 " SIZE_FORMAT,
      min_gen0_size(), initial_gen0_size(), max_gen0_size());
  }
}
예제 #12
0
size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size,
                                                 size_t maximum_size) {
  size_t alignment = min_alignment();
  size_t max_minus = maximum_size - alignment;
  return desired_size < max_minus ? desired_size : max_minus;
}
예제 #13
0
void TwoGenerationCollectorPolicy::initialize_flags() {
  // All space sizes must be multiples of car size in order for the
  // CarTable to work.  Similarly with the should_scavenge region size.
  set_min_alignment(MAX2((uintx) CarSpace::car_size(), (uintx) Generation::GenGrain));

  // The card marking array and the offset arrays for old generations are
  // committed in os pages as well. Make sure they are entirely full (to
  // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
  // byte entry and the os page size is 4096, the maximum heap size should
  // be 512*4096 = 2MB aligned.
  set_max_alignment(GenRemSet::max_alignment_constraint(rem_set_name()));
  assert(max_alignment() >= min_alignment() && max_alignment() % min_alignment() == 0, "invalid alignment constraints");

  // Adjust max size parameters
  if (NewSize > MaxNewSize) {
    MaxNewSize = NewSize;
  }
  NewSize = align_size_down(NewSize, min_alignment());
  MaxNewSize = align_size_down(MaxNewSize, min_alignment());

  OldSize = align_size_down(OldSize, min_alignment());
  if (NewSize + OldSize > MaxHeapSize) {
    MaxHeapSize = NewSize + OldSize;
  }
  MaxHeapSize = align_size_up(MaxHeapSize, max_alignment());

  if (PermSize > MaxPermSize) {
    MaxPermSize = PermSize;
  }
  PermSize = align_size_down(PermSize, min_alignment());
  MaxPermSize = align_size_down(MaxPermSize, max_alignment());

  MinPermHeapExpansion = align_size_down(MinPermHeapExpansion, min_alignment());
  MaxPermHeapExpansion = align_size_down(MaxPermHeapExpansion, min_alignment());

  MinHeapDeltaBytes = align_size_up(MinHeapDeltaBytes, min_alignment());

  always_do_update_barrier = UseConcMarkSweepGC;
  BlockOffsetArrayUseUnallocatedBlock |= ParallelGCThreads > 0;

  SharedReadOnlySize = align_size_up(SharedReadOnlySize, max_alignment());
  SharedReadWriteSize = align_size_up(SharedReadWriteSize, max_alignment());
  SharedMiscDataSize = align_size_up(SharedMiscDataSize, max_alignment());

  // Check validity of heap flags
  assert(NewSize     % min_alignment() == 0, "eden space alignment");
  assert(MaxNewSize  % min_alignment() == 0, "survivor space alignment");
  assert(OldSize     % min_alignment() == 0, "old space alignment");
  assert(MaxHeapSize % max_alignment() == 0, "maximum heap alignment");
  assert(PermSize    % min_alignment() == 0, "permanent space alignment");
  assert(MaxPermSize % max_alignment() == 0, "maximum permanent space alignment");
  assert(SharedReadOnlySize % max_alignment() == 0, "read-only space alignment");
  assert(SharedReadWriteSize % max_alignment() == 0, "read-write space alignment");
  assert(SharedMiscDataSize % max_alignment() == 0, "misc-data space alignment");

  if (NewSize < 3*min_alignment()) {
     // make sure there room for eden and two survivor spaces
    vm_exit_during_initialization("Too small new size specified");
  }
  if (PermSize < M) {
    vm_exit_during_initialization("Too small initial permanent heap");
  }
  if (SurvivorRatio < 1 || NewRatio < 1) {
    vm_exit_during_initialization("Invalid heap ratio specified");
  }
}
void ParallelScavengeHeap::initialize() {
  // Cannot be initialized until after the flags are parsed
  GenerationSizer flag_parser;

  const size_t alignment = min_alignment();

  // Check alignments
// NEEDS_CLEANUP   The default TwoGenerationCollectorPolicy uses
//   NewRatio;  it should check UseAdaptiveSizePolicy. Changes from
//   generationSizer could move to the common code.
  size_t young_size = align_size_up(flag_parser.young_gen_size(), alignment);
  size_t max_young_size = align_size_up(flag_parser.max_young_gen_size(), 
                                                                  alignment);

  size_t old_size = align_size_up(flag_parser.old_gen_size(), alignment);
  size_t max_old_size = align_size_up(flag_parser.max_old_gen_size(), 
                                                                  alignment);

  size_t perm_size = align_size_up(flag_parser.perm_gen_size(), alignment);
  size_t max_perm_size = align_size_up(flag_parser.max_perm_gen_size(), 
                                                                  alignment);

  // Calculate the total size.
  size_t total_reserved = max_young_size + max_old_size + max_perm_size;

  if (UseISM || UsePermISM) {
    total_reserved = round_to(total_reserved, LargePageSizeInBytes);
  }

  ReservedSpace heap_rs(total_reserved, alignment, UseISM || UsePermISM);
  if (!heap_rs.is_reserved()) {
    vm_exit_during_initialization("Could not reserve enough space for "
                                  "object heap");
  }

  _reserved = MemRegion((HeapWord*)heap_rs.base(),
			(HeapWord*)(heap_rs.base() + heap_rs.size()));

  HeapWord* boundary = (HeapWord*)(heap_rs.base() + max_young_size);
  CardTableExtension* card_table_barrier_set = new CardTableExtension(_reserved, 3);
  _barrier_set = card_table_barrier_set;

  oopDesc::set_bs(_barrier_set);
  if (_barrier_set == NULL) {
    vm_exit_during_initialization("Could not reserve enough space for "
                                  "barrier set"); 
  }

  // Initial young gen size is 4 Mb
  size_t init_young_size = align_size_up(4 * M, alignment);
  init_young_size = MAX2(MIN2(init_young_size, max_young_size), young_size);

  ReservedSpace generation_rs = heap_rs.first_part(max_young_size);
  _young_gen = new PSYoungGen(generation_rs, 
                              init_young_size, 
                              young_size, 
                              max_young_size);
  heap_rs = heap_rs.last_part(max_young_size);

  generation_rs = heap_rs.first_part(max_old_size);
  _old_gen = new PSOldGen(generation_rs,
                          old_size,
                          old_size,
                          max_old_size,
                          "old", 1);

  heap_rs = heap_rs.last_part(max_old_size);

  _perm_gen = new PSPermGen(heap_rs,
                            perm_size,
                            perm_size,
                            max_perm_size,
                            "perm", 2);

  _size_policy = new AdaptiveSizePolicy(young_gen()->eden_space()->capacity_in_bytes(),
                                        old_gen()->capacity_in_bytes(),
                                        young_gen()->to_space()->capacity_in_bytes(),
                                        max_young_size,
                                        max_old_size,
                                        alignment);

  // initialize the policy counters - 2 collectors, 3 generations
  _gc_policy_counters = new GCPolicyCounters(PERF_GC, "ParScav:MSC", 2, 3);
}