예제 #1
0
// This method assumes that from-space has live data and that
// any shrinkage of the young gen is limited by location of
// from-space.
size_t ASParNewGeneration::available_to_live() const {
#undef SHRINKS_AT_END_OF_EDEN
#ifdef SHRINKS_AT_END_OF_EDEN
  size_t delta_in_survivor = 0;
  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
  const size_t space_alignment = heap->intra_heap_alignment();
  const size_t gen_alignment = heap->object_heap_alignment();

  MutableSpace* space_shrinking = NULL;
  if (from_space()->end() > to_space()->end()) {
    space_shrinking = from_space();
  } else {
    space_shrinking = to_space();
  }

  // Include any space that is committed but not included in
  // the survivor spaces.
  assert(((HeapWord*)virtual_space()->high()) >= space_shrinking->end(),
    "Survivor space beyond high end");
  size_t unused_committed = pointer_delta(virtual_space()->high(),
    space_shrinking->end(), sizeof(char));

  if (space_shrinking->is_empty()) {
    // Don't let the space shrink to 0
    assert(space_shrinking->capacity_in_bytes() >= space_alignment,
      "Space is too small");
    delta_in_survivor = space_shrinking->capacity_in_bytes() - space_alignment;
  } else {
    delta_in_survivor = pointer_delta(space_shrinking->end(),
                                      space_shrinking->top(),
                                      sizeof(char));
  }

  size_t delta_in_bytes = unused_committed + delta_in_survivor;
  delta_in_bytes = align_size_down(delta_in_bytes, gen_alignment);
  return delta_in_bytes;
#else
  // The only space available for shrinking is in to-space if it
  // is above from-space.
  if (to()->bottom() > from()->bottom()) {
    const size_t alignment = os::vm_page_size();
    if (to()->capacity() < alignment) {
      return 0;
    } else {
      return to()->capacity() - alignment;
    }
  } else {
    return 0;
  }
#endif
}