src/share/vm/memory/metaspace.cpp

changeset 5015
868d87ed63c8
parent 5007
c23dbf0e8ab7
child 5023
601183f604b2
     1.1 --- a/src/share/vm/memory/metaspace.cpp	Thu Apr 18 10:09:23 2013 -0700
     1.2 +++ b/src/share/vm/memory/metaspace.cpp	Tue Feb 12 14:15:45 2013 -0800
     1.3 @@ -47,7 +47,6 @@
     1.4  // the free chunk lists
     1.5  const bool metaspace_slow_verify = false;
     1.6  
     1.7 -
     1.8  // Parameters for stress mode testing
     1.9  const uint metadata_deallocate_a_lot_block = 10;
    1.10  const uint metadata_deallocate_a_lock_chunk = 3;
    1.11 @@ -220,7 +219,6 @@
    1.12    void print_on(outputStream* st);
    1.13  };
    1.14  
    1.15 -
    1.16  // Used to manage the free list of Metablocks (a block corresponds
    1.17  // to the allocation of a quantum of metadata).
    1.18  class BlockFreelist VALUE_OBJ_CLASS_SPEC {
    1.19 @@ -298,7 +296,7 @@
    1.20    MemRegion* reserved() { return &_reserved; }
    1.21    VirtualSpace* virtual_space() const { return (VirtualSpace*) &_virtual_space; }
    1.22  
    1.23 -  // Returns true if "word_size" is available in the virtual space
    1.24 +  // Returns true if "word_size" is available in the VirtualSpace
    1.25    bool is_available(size_t word_size) { return _top + word_size <= end(); }
    1.26  
    1.27    MetaWord* top() const { return _top; }
    1.28 @@ -313,6 +311,7 @@
    1.29    // used and capacity in this single entry in the list
    1.30    size_t used_words_in_vs() const;
    1.31    size_t capacity_words_in_vs() const;
    1.32 +  size_t free_words_in_vs() const;
    1.33  
    1.34    bool initialize();
    1.35  
    1.36 @@ -449,6 +448,8 @@
    1.37    VirtualSpaceList(size_t word_size);
    1.38    VirtualSpaceList(ReservedSpace rs);
    1.39  
    1.40 +  size_t free_bytes();
    1.41 +
    1.42    Metachunk* get_new_chunk(size_t word_size,
    1.43                             size_t grow_chunks_by_words,
    1.44                             size_t medium_chunk_bunch);
    1.45 @@ -579,7 +580,11 @@
    1.46    bool has_small_chunk_limit() { return !vs_list()->is_class(); }
    1.47  
    1.48    // Sum of all space in allocated chunks
    1.49 -  size_t _allocation_total;
    1.50 +  size_t _allocated_blocks_words;
    1.51 +
    1.52 +  // Sum of all allocated chunks
    1.53 +  size_t _allocated_chunks_words;
    1.54 +  size_t _allocated_chunks_count;
    1.55  
    1.56    // Free lists of blocks are per SpaceManager since they
    1.57    // are assumed to be in chunks in use by the SpaceManager
    1.58 @@ -635,12 +640,27 @@
    1.59    size_t medium_chunk_size() { return (size_t) vs_list()->is_class() ? ClassMediumChunk : MediumChunk; }
    1.60    size_t medium_chunk_bunch() { return medium_chunk_size() * MediumChunkMultiple; }
    1.61  
    1.62 -  size_t allocation_total() const { return _allocation_total; }
    1.63 -  void inc_allocation_total(size_t v) { Atomic::add_ptr(v, &_allocation_total); }
    1.64 +  size_t allocated_blocks_words() const { return _allocated_blocks_words; }
    1.65 +  size_t allocated_blocks_bytes() const { return _allocated_blocks_words * BytesPerWord; }
    1.66 +  size_t allocated_chunks_words() const { return _allocated_chunks_words; }
    1.67 +  size_t allocated_chunks_count() const { return _allocated_chunks_count; }
    1.68 +
    1.69    bool is_humongous(size_t word_size) { return word_size > medium_chunk_size(); }
    1.70  
    1.71    static Mutex* expand_lock() { return _expand_lock; }
    1.72  
    1.73 +  // Increment the per Metaspace and global running sums for Metachunks
    1.74 +  // by the given size.  This is used when a Metachunk to added to
    1.75 +  // the in-use list.
    1.76 +  void inc_size_metrics(size_t words);
    1.77 +  // Increment the per Metaspace and global running sums Metablocks by the given
    1.78 +  // size.  This is used when a Metablock is allocated.
    1.79 +  void inc_used_metrics(size_t words);
    1.80 +  // Delete the portion of the running sums for this SpaceManager. That is,
    1.81 +  // the globals running sums for the Metachunks and Metablocks are
    1.82 +  // decremented for all the Metachunks in-use by this SpaceManager.
    1.83 +  void dec_total_from_size_metrics();
    1.84 +
    1.85    // Set the sizes for the initial chunks.
    1.86    void get_initial_chunk_sizes(Metaspace::MetaspaceType type,
    1.87                                 size_t* chunk_word_size,
    1.88 @@ -686,7 +706,7 @@
    1.89    void verify_chunk_size(Metachunk* chunk);
    1.90    NOT_PRODUCT(void mangle_freed_chunks();)
    1.91  #ifdef ASSERT
    1.92 -  void verify_allocation_total();
    1.93 +  void verify_allocated_blocks_words();
    1.94  #endif
    1.95  };
    1.96  
    1.97 @@ -797,6 +817,9 @@
    1.98    return pointer_delta(end(), bottom(), sizeof(MetaWord));
    1.99  }
   1.100  
   1.101 +size_t VirtualSpaceNode::free_words_in_vs() const {
   1.102 +  return pointer_delta(end(), top(), sizeof(MetaWord));
   1.103 +}
   1.104  
   1.105  // Allocates the chunk from the virtual space only.
   1.106  // This interface is also used internally for debugging.  Not all
   1.107 @@ -1071,6 +1094,10 @@
   1.108    link_vs(class_entry, rs.size()/BytesPerWord);
   1.109  }
   1.110  
   1.111 +size_t VirtualSpaceList::free_bytes() {
   1.112 +  return virtual_space_list()->free_words_in_vs() * BytesPerWord;
   1.113 +}
   1.114 +
   1.115  // Allocate another meta virtual space and add it to the list.
   1.116  bool VirtualSpaceList::grow_vs(size_t vs_word_size) {
   1.117    assert_lock_strong(SpaceManager::expand_lock());
   1.118 @@ -1211,9 +1238,9 @@
   1.119  //
   1.120  // After the GC the compute_new_size() for MetaspaceGC is called to
   1.121  // resize the capacity of the metaspaces.  The current implementation
   1.122 -// is based on the flags MinMetaspaceFreeRatio and MaxHeapFreeRatio used
   1.123 +// is based on the flags MinMetaspaceFreeRatio and MaxMetaspaceFreeRatio used
   1.124  // to resize the Java heap by some GC's.  New flags can be implemented
   1.125 -// if really needed.  MinHeapFreeRatio is used to calculate how much
   1.126 +// if really needed.  MinMetaspaceFreeRatio is used to calculate how much
   1.127  // free space is desirable in the metaspace capacity to decide how much
   1.128  // to increase the HWM.  MaxMetaspaceFreeRatio is used to decide how much
   1.129  // free space is desirable in the metaspace capacity before decreasing
   1.130 @@ -1248,7 +1275,11 @@
   1.131  }
   1.132  
   1.133  bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) {
   1.134 +
   1.135 +  size_t committed_capacity_bytes = MetaspaceAux::allocated_capacity_bytes();
   1.136    // If the user wants a limit, impose one.
   1.137 +  size_t max_metaspace_size_bytes = MaxMetaspaceSize;
   1.138 +  size_t metaspace_size_bytes = MetaspaceSize;
   1.139    if (!FLAG_IS_DEFAULT(MaxMetaspaceSize) &&
   1.140        MetaspaceAux::reserved_in_bytes() >= MaxMetaspaceSize) {
   1.141      return false;
   1.142 @@ -1260,57 +1291,48 @@
   1.143  
   1.144    // If this is part of an allocation after a GC, expand
   1.145    // unconditionally.
   1.146 -  if(MetaspaceGC::expand_after_GC()) {
   1.147 +  if (MetaspaceGC::expand_after_GC()) {
   1.148      return true;
   1.149    }
   1.150  
   1.151 -  size_t metaspace_size_words = MetaspaceSize / BytesPerWord;
   1.152 +
   1.153  
   1.154    // If the capacity is below the minimum capacity, allow the
   1.155    // expansion.  Also set the high-water-mark (capacity_until_GC)
   1.156    // to that minimum capacity so that a GC will not be induced
   1.157    // until that minimum capacity is exceeded.
   1.158 -  if (vsl->capacity_words_sum() < metaspace_size_words ||
   1.159 +  if (committed_capacity_bytes < metaspace_size_bytes ||
   1.160        capacity_until_GC() == 0) {
   1.161 -    set_capacity_until_GC(metaspace_size_words);
   1.162 +    set_capacity_until_GC(metaspace_size_bytes);
   1.163      return true;
   1.164    } else {
   1.165 -    if (vsl->capacity_words_sum() < capacity_until_GC()) {
   1.166 +    if (committed_capacity_bytes < capacity_until_GC()) {
   1.167        return true;
   1.168      } else {
   1.169        if (TraceMetadataChunkAllocation && Verbose) {
   1.170          gclog_or_tty->print_cr("  allocation request size " SIZE_FORMAT
   1.171                          "  capacity_until_GC " SIZE_FORMAT
   1.172 -                        "  capacity_words_sum " SIZE_FORMAT
   1.173 -                        "  used_words_sum " SIZE_FORMAT
   1.174 -                        "  free chunks " SIZE_FORMAT
   1.175 -                        "  free chunks count %d",
   1.176 +                        "  allocated_capacity_bytes " SIZE_FORMAT,
   1.177                          word_size,
   1.178                          capacity_until_GC(),
   1.179 -                        vsl->capacity_words_sum(),
   1.180 -                        vsl->used_words_sum(),
   1.181 -                        vsl->chunk_manager()->free_chunks_total(),
   1.182 -                        vsl->chunk_manager()->free_chunks_count());
   1.183 +                        MetaspaceAux::allocated_capacity_bytes());
   1.184        }
   1.185        return false;
   1.186      }
   1.187    }
   1.188  }
   1.189  
   1.190 -// Variables are in bytes
   1.191 +
   1.192  
   1.193  void MetaspaceGC::compute_new_size() {
   1.194    assert(_shrink_factor <= 100, "invalid shrink factor");
   1.195    uint current_shrink_factor = _shrink_factor;
   1.196    _shrink_factor = 0;
   1.197  
   1.198 -  VirtualSpaceList *vsl = Metaspace::space_list();
   1.199 -
   1.200 -  size_t capacity_after_gc = vsl->capacity_bytes_sum();
   1.201 -  // Check to see if these two can be calculated without walking the CLDG
   1.202 -  size_t used_after_gc = vsl->used_bytes_sum();
   1.203 -  size_t capacity_until_GC = vsl->capacity_bytes_sum();
   1.204 -  size_t free_after_gc = capacity_until_GC - used_after_gc;
   1.205 +  // Until a faster way of calculating the "used" quantity is implemented,
   1.206 +  // use "capacity".
   1.207 +  const size_t used_after_gc = MetaspaceAux::allocated_capacity_bytes();
   1.208 +  const size_t capacity_until_GC = MetaspaceGC::capacity_until_GC();
   1.209  
   1.210    const double minimum_free_percentage = MinMetaspaceFreeRatio / 100.0;
   1.211    const double maximum_used_percentage = 1.0 - minimum_free_percentage;
   1.212 @@ -1323,45 +1345,34 @@
   1.213                                    MetaspaceSize);
   1.214  
   1.215    if (PrintGCDetails && Verbose) {
   1.216 -    const double free_percentage = ((double)free_after_gc) / capacity_until_GC;
   1.217      gclog_or_tty->print_cr("\nMetaspaceGC::compute_new_size: ");
   1.218      gclog_or_tty->print_cr("  "
   1.219                    "  minimum_free_percentage: %6.2f"
   1.220                    "  maximum_used_percentage: %6.2f",
   1.221                    minimum_free_percentage,
   1.222                    maximum_used_percentage);
   1.223 -    double d_free_after_gc = free_after_gc / (double) K;
   1.224      gclog_or_tty->print_cr("  "
   1.225 -                  "   free_after_gc       : %6.1fK"
   1.226 -                  "   used_after_gc       : %6.1fK"
   1.227 -                  "   capacity_after_gc   : %6.1fK"
   1.228 -                  "   metaspace HWM     : %6.1fK",
   1.229 -                  free_after_gc / (double) K,
   1.230 -                  used_after_gc / (double) K,
   1.231 -                  capacity_after_gc / (double) K,
   1.232 -                  capacity_until_GC / (double) K);
   1.233 -    gclog_or_tty->print_cr("  "
   1.234 -                  "   free_percentage: %6.2f",
   1.235 -                  free_percentage);
   1.236 +                  "   used_after_gc       : %6.1fKB",
   1.237 +                  used_after_gc / (double) K);
   1.238    }
   1.239  
   1.240  
   1.241 +  size_t shrink_bytes = 0;
   1.242    if (capacity_until_GC < minimum_desired_capacity) {
   1.243      // If we have less capacity below the metaspace HWM, then
   1.244      // increment the HWM.
   1.245      size_t expand_bytes = minimum_desired_capacity - capacity_until_GC;
   1.246      // Don't expand unless it's significant
   1.247      if (expand_bytes >= MinMetaspaceExpansion) {
   1.248 -      size_t expand_words = expand_bytes / BytesPerWord;
   1.249 -      MetaspaceGC::inc_capacity_until_GC(expand_words);
   1.250 +      MetaspaceGC::set_capacity_until_GC(capacity_until_GC + expand_bytes);
   1.251      }
   1.252      if (PrintGCDetails && Verbose) {
   1.253 -      size_t new_capacity_until_GC = MetaspaceGC::capacity_until_GC_in_bytes();
   1.254 +      size_t new_capacity_until_GC = capacity_until_GC;
   1.255        gclog_or_tty->print_cr("    expanding:"
   1.256 -                    "  minimum_desired_capacity: %6.1fK"
   1.257 -                    "  expand_words: %6.1fK"
   1.258 -                    "  MinMetaspaceExpansion: %6.1fK"
   1.259 -                    "  new metaspace HWM:  %6.1fK",
   1.260 +                    "  minimum_desired_capacity: %6.1fKB"
   1.261 +                    "  expand_bytes: %6.1fKB"
   1.262 +                    "  MinMetaspaceExpansion: %6.1fKB"
   1.263 +                    "  new metaspace HWM:  %6.1fKB",
   1.264                      minimum_desired_capacity / (double) K,
   1.265                      expand_bytes / (double) K,
   1.266                      MinMetaspaceExpansion / (double) K,
   1.267 @@ -1371,11 +1382,10 @@
   1.268    }
   1.269  
   1.270    // No expansion, now see if we want to shrink
   1.271 -  size_t shrink_words = 0;
   1.272    // We would never want to shrink more than this
   1.273 -  size_t max_shrink_words = capacity_until_GC - minimum_desired_capacity;
   1.274 -  assert(max_shrink_words >= 0, err_msg("max_shrink_words " SIZE_FORMAT,
   1.275 -    max_shrink_words));
   1.276 +  size_t max_shrink_bytes = capacity_until_GC - minimum_desired_capacity;
   1.277 +  assert(max_shrink_bytes >= 0, err_msg("max_shrink_bytes " SIZE_FORMAT,
   1.278 +    max_shrink_bytes));
   1.279  
   1.280    // Should shrinking be considered?
   1.281    if (MaxMetaspaceFreeRatio < 100) {
   1.282 @@ -1385,17 +1395,15 @@
   1.283      size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(max_uintx));
   1.284      maximum_desired_capacity = MAX2(maximum_desired_capacity,
   1.285                                      MetaspaceSize);
   1.286 -    if (PrintGC && Verbose) {
   1.287 +    if (PrintGCDetails && Verbose) {
   1.288        gclog_or_tty->print_cr("  "
   1.289                               "  maximum_free_percentage: %6.2f"
   1.290                               "  minimum_used_percentage: %6.2f",
   1.291                               maximum_free_percentage,
   1.292                               minimum_used_percentage);
   1.293        gclog_or_tty->print_cr("  "
   1.294 -                             "  capacity_until_GC: %6.1fK"
   1.295 -                             "  minimum_desired_capacity: %6.1fK"
   1.296 -                             "  maximum_desired_capacity: %6.1fK",
   1.297 -                             capacity_until_GC / (double) K,
   1.298 +                             "  minimum_desired_capacity: %6.1fKB"
   1.299 +                             "  maximum_desired_capacity: %6.1fKB",
   1.300                               minimum_desired_capacity / (double) K,
   1.301                               maximum_desired_capacity / (double) K);
   1.302      }
   1.303 @@ -1405,17 +1413,17 @@
   1.304  
   1.305      if (capacity_until_GC > maximum_desired_capacity) {
   1.306        // Capacity too large, compute shrinking size
   1.307 -      shrink_words = capacity_until_GC - maximum_desired_capacity;
   1.308 +      shrink_bytes = capacity_until_GC - maximum_desired_capacity;
   1.309        // We don't want shrink all the way back to initSize if people call
   1.310        // System.gc(), because some programs do that between "phases" and then
   1.311        // we'd just have to grow the heap up again for the next phase.  So we
   1.312        // damp the shrinking: 0% on the first call, 10% on the second call, 40%
   1.313        // on the third call, and 100% by the fourth call.  But if we recompute
   1.314        // size without shrinking, it goes back to 0%.
   1.315 -      shrink_words = shrink_words / 100 * current_shrink_factor;
   1.316 -      assert(shrink_words <= max_shrink_words,
   1.317 +      shrink_bytes = shrink_bytes / 100 * current_shrink_factor;
   1.318 +      assert(shrink_bytes <= max_shrink_bytes,
   1.319          err_msg("invalid shrink size " SIZE_FORMAT " not <= " SIZE_FORMAT,
   1.320 -          shrink_words, max_shrink_words));
   1.321 +          shrink_bytes, max_shrink_bytes));
   1.322        if (current_shrink_factor == 0) {
   1.323          _shrink_factor = 10;
   1.324        } else {
   1.325 @@ -1429,11 +1437,11 @@
   1.326                        MetaspaceSize / (double) K,
   1.327                        maximum_desired_capacity / (double) K);
   1.328          gclog_or_tty->print_cr("  "
   1.329 -                      "  shrink_words: %.1fK"
   1.330 +                      "  shrink_bytes: %.1fK"
   1.331                        "  current_shrink_factor: %d"
   1.332                        "  new shrink factor: %d"
   1.333                        "  MinMetaspaceExpansion: %.1fK",
   1.334 -                      shrink_words / (double) K,
   1.335 +                      shrink_bytes / (double) K,
   1.336                        current_shrink_factor,
   1.337                        _shrink_factor,
   1.338                        MinMetaspaceExpansion / (double) K);
   1.339 @@ -1441,23 +1449,11 @@
   1.340      }
   1.341    }
   1.342  
   1.343 -
   1.344    // Don't shrink unless it's significant
   1.345 -  if (shrink_words >= MinMetaspaceExpansion) {
   1.346 -    VirtualSpaceNode* csp = vsl->current_virtual_space();
   1.347 -    size_t available_to_shrink = csp->capacity_words_in_vs() -
   1.348 -      csp->used_words_in_vs();
   1.349 -    shrink_words = MIN2(shrink_words, available_to_shrink);
   1.350 -    csp->shrink_by(shrink_words);
   1.351 -    MetaspaceGC::dec_capacity_until_GC(shrink_words);
   1.352 -    if (PrintGCDetails && Verbose) {
   1.353 -      size_t new_capacity_until_GC = MetaspaceGC::capacity_until_GC_in_bytes();
   1.354 -      gclog_or_tty->print_cr("  metaspace HWM: %.1fK", new_capacity_until_GC / (double) K);
   1.355 -    }
   1.356 +  if (shrink_bytes >= MinMetaspaceExpansion &&
   1.357 +      ((capacity_until_GC - shrink_bytes) >= MetaspaceSize)) {
   1.358 +    MetaspaceGC::set_capacity_until_GC(capacity_until_GC - shrink_bytes);
   1.359    }
   1.360 -  assert(used_after_gc <= vsl->capacity_bytes_sum(),
   1.361 -         "sanity check");
   1.362 -
   1.363  }
   1.364  
   1.365  // Metadebug methods
   1.366 @@ -1860,18 +1856,28 @@
   1.367  }
   1.368  
   1.369  size_t SpaceManager::sum_capacity_in_chunks_in_use() const {
   1.370 -  MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
   1.371 -  size_t sum = 0;
   1.372 -  for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
   1.373 -    Metachunk* chunk = chunks_in_use(i);
   1.374 -    while (chunk != NULL) {
   1.375 -      // Just changed this sum += chunk->capacity_word_size();
   1.376 -      // sum += chunk->word_size() - Metachunk::overhead();
   1.377 -      sum += chunk->capacity_word_size();
   1.378 -      chunk = chunk->next();
   1.379 +  // For CMS use "allocated_chunks_words()" which does not need the
   1.380 +  // Metaspace lock.  For the other collectors sum over the
   1.381 +  // lists.  Use both methods as a check that "allocated_chunks_words()"
   1.382 +  // is correct.  That is, sum_capacity_in_chunks() is too expensive
   1.383 +  // to use in the product and allocated_chunks_words() should be used
   1.384 +  // but allow for  checking that allocated_chunks_words() returns the same
   1.385 +  // value as sum_capacity_in_chunks_in_use() which is the definitive
   1.386 +  // answer.
   1.387 +  if (UseConcMarkSweepGC) {
   1.388 +    return allocated_chunks_words();
   1.389 +  } else {
   1.390 +    MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
   1.391 +    size_t sum = 0;
   1.392 +    for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
   1.393 +      Metachunk* chunk = chunks_in_use(i);
   1.394 +      while (chunk != NULL) {
   1.395 +        sum += chunk->capacity_word_size();
   1.396 +        chunk = chunk->next();
   1.397 +      }
   1.398      }
   1.399 +  return sum;
   1.400    }
   1.401 -  return sum;
   1.402  }
   1.403  
   1.404  size_t SpaceManager::sum_count_in_chunks_in_use() {
   1.405 @@ -2029,12 +2035,44 @@
   1.406  SpaceManager::SpaceManager(Mutex* lock,
   1.407                             VirtualSpaceList* vs_list) :
   1.408    _vs_list(vs_list),
   1.409 -  _allocation_total(0),
   1.410 +  _allocated_blocks_words(0),
   1.411 +  _allocated_chunks_words(0),
   1.412 +  _allocated_chunks_count(0),
   1.413    _lock(lock)
   1.414  {
   1.415    initialize();
   1.416  }
   1.417  
   1.418 +void SpaceManager::inc_size_metrics(size_t words) {
   1.419 +  assert_lock_strong(SpaceManager::expand_lock());
   1.420 +  // Total of allocated Metachunks and allocated Metachunks count
   1.421 +  // for each SpaceManager
   1.422 +  _allocated_chunks_words = _allocated_chunks_words + words;
   1.423 +  _allocated_chunks_count++;
   1.424 +  // Global total of capacity in allocated Metachunks
   1.425 +  MetaspaceAux::inc_capacity(words);
   1.426 +  // Global total of allocated Metablocks.
   1.427 +  // used_words_slow() includes the overhead in each
   1.428 +  // Metachunk so include it in the used when the
   1.429 +  // Metachunk is first added (so only added once per
   1.430 +  // Metachunk).
   1.431 +  MetaspaceAux::inc_used(Metachunk::overhead());
   1.432 +}
   1.433 +
   1.434 +void SpaceManager::inc_used_metrics(size_t words) {
   1.435 +  // Add to the per SpaceManager total
   1.436 +  Atomic::add_ptr(words, &_allocated_blocks_words);
   1.437 +  // Add to the global total
   1.438 +  MetaspaceAux::inc_used(words);
   1.439 +}
   1.440 +
   1.441 +void SpaceManager::dec_total_from_size_metrics() {
   1.442 +  MetaspaceAux::dec_capacity(allocated_chunks_words());
   1.443 +  MetaspaceAux::dec_used(allocated_blocks_words());
   1.444 +  // Also deduct the overhead per Metachunk
   1.445 +  MetaspaceAux::dec_used(allocated_chunks_count() * Metachunk::overhead());
   1.446 +}
   1.447 +
   1.448  void SpaceManager::initialize() {
   1.449    Metadebug::init_allocation_fail_alot_count();
   1.450    for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
   1.451 @@ -2073,7 +2111,10 @@
   1.452  
   1.453  SpaceManager::~SpaceManager() {
   1.454    // This call this->_lock which can't be done while holding expand_lock()
   1.455 -  const size_t in_use_before = sum_capacity_in_chunks_in_use();
   1.456 +  assert(sum_capacity_in_chunks_in_use() == allocated_chunks_words(),
   1.457 +    err_msg("sum_capacity_in_chunks_in_use() " SIZE_FORMAT
   1.458 +            " allocated_chunks_words() " SIZE_FORMAT,
   1.459 +            sum_capacity_in_chunks_in_use(), allocated_chunks_words()));
   1.460  
   1.461    MutexLockerEx fcl(SpaceManager::expand_lock(),
   1.462                      Mutex::_no_safepoint_check_flag);
   1.463 @@ -2082,6 +2123,8 @@
   1.464  
   1.465    chunk_manager->slow_locked_verify();
   1.466  
   1.467 +  dec_total_from_size_metrics();
   1.468 +
   1.469    if (TraceMetadataChunkAllocation && Verbose) {
   1.470      gclog_or_tty->print_cr("~SpaceManager(): " PTR_FORMAT, this);
   1.471      locked_print_chunks_in_use_on(gclog_or_tty);
   1.472 @@ -2092,7 +2135,7 @@
   1.473  
   1.474    // Have to update before the chunks_in_use lists are emptied
   1.475    // below.
   1.476 -  chunk_manager->inc_free_chunks_total(in_use_before,
   1.477 +  chunk_manager->inc_free_chunks_total(allocated_chunks_words(),
   1.478                                         sum_count_in_chunks_in_use());
   1.479  
   1.480    // Add all the chunks in use by this space manager
   1.481 @@ -2158,7 +2201,6 @@
   1.482                       chunk_manager->humongous_dictionary()->total_count(),
   1.483                       chunk_size_name(HumongousIndex));
   1.484    }
   1.485 -  set_chunks_in_use(HumongousIndex, NULL);
   1.486    chunk_manager->slow_locked_verify();
   1.487  }
   1.488  
   1.489 @@ -2238,12 +2280,17 @@
   1.490      assert(new_chunk->word_size() > medium_chunk_size(), "List inconsistency");
   1.491    }
   1.492  
   1.493 +  // Add to the running sum of capacity
   1.494 +  inc_size_metrics(new_chunk->word_size());
   1.495 +
   1.496    assert(new_chunk->is_empty(), "Not ready for reuse");
   1.497    if (TraceMetadataChunkAllocation && Verbose) {
   1.498      gclog_or_tty->print("SpaceManager::add_chunk: %d) ",
   1.499                          sum_count_in_chunks_in_use());
   1.500      new_chunk->print_on(gclog_or_tty);
   1.501 -    vs_list()->chunk_manager()->locked_print_free_chunks(tty);
   1.502 +    if (vs_list() != NULL) {
   1.503 +      vs_list()->chunk_manager()->locked_print_free_chunks(tty);
   1.504 +    }
   1.505    }
   1.506  }
   1.507  
   1.508 @@ -2314,7 +2361,7 @@
   1.509    // of memory if this returns null.
   1.510    if (DumpSharedSpaces) {
   1.511      assert(current_chunk() != NULL, "should never happen");
   1.512 -    inc_allocation_total(word_size);
   1.513 +    inc_used_metrics(word_size);
   1.514      return current_chunk()->allocate(word_size); // caller handles null result
   1.515    }
   1.516    if (current_chunk() != NULL) {
   1.517 @@ -2325,7 +2372,7 @@
   1.518      result = grow_and_allocate(word_size);
   1.519    }
   1.520    if (result > 0) {
   1.521 -    inc_allocation_total(word_size);
   1.522 +    inc_used_metrics(word_size);
   1.523      assert(result != (MetaWord*) chunks_in_use(MediumIndex),
   1.524             "Head of the list is being allocated");
   1.525    }
   1.526 @@ -2359,20 +2406,14 @@
   1.527  }
   1.528  
   1.529  #ifdef ASSERT
   1.530 -void SpaceManager::verify_allocation_total() {
   1.531 +void SpaceManager::verify_allocated_blocks_words() {
   1.532    // Verification is only guaranteed at a safepoint.
   1.533 -  if (SafepointSynchronize::is_at_safepoint()) {
   1.534 -    gclog_or_tty->print_cr("Chunk " PTR_FORMAT " allocation_total " SIZE_FORMAT
   1.535 -                           " sum_used_in_chunks_in_use " SIZE_FORMAT,
   1.536 -                           this,
   1.537 -                           allocation_total(),
   1.538 -                           sum_used_in_chunks_in_use());
   1.539 -  }
   1.540 -  MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
   1.541 -  assert(allocation_total() == sum_used_in_chunks_in_use(),
   1.542 +  assert(SafepointSynchronize::is_at_safepoint() || !Universe::is_fully_initialized(),
   1.543 +    "Verification can fail if the applications is running");
   1.544 +  assert(allocated_blocks_words() == sum_used_in_chunks_in_use(),
   1.545      err_msg("allocation total is not consistent " SIZE_FORMAT
   1.546              " vs " SIZE_FORMAT,
   1.547 -            allocation_total(), sum_used_in_chunks_in_use()));
   1.548 +            allocated_blocks_words(), sum_used_in_chunks_in_use()));
   1.549  }
   1.550  
   1.551  #endif
   1.552 @@ -2428,14 +2469,65 @@
   1.553  
   1.554  // MetaspaceAux
   1.555  
   1.556 -size_t MetaspaceAux::used_in_bytes(Metaspace::MetadataType mdtype) {
   1.557 +
   1.558 +size_t MetaspaceAux::_allocated_capacity_words = 0;
   1.559 +size_t MetaspaceAux::_allocated_used_words = 0;
   1.560 +
   1.561 +size_t MetaspaceAux::free_bytes() {
   1.562 +  size_t result = 0;
   1.563 +  if (Metaspace::class_space_list() != NULL) {
   1.564 +    result = result + Metaspace::class_space_list()->free_bytes();
   1.565 +  }
   1.566 +  if (Metaspace::space_list() != NULL) {
   1.567 +    result = result + Metaspace::space_list()->free_bytes();
   1.568 +  }
   1.569 +  return result;
   1.570 +}
   1.571 +
   1.572 +void MetaspaceAux::dec_capacity(size_t words) {
   1.573 +  assert_lock_strong(SpaceManager::expand_lock());
   1.574 +  assert(words <= _allocated_capacity_words,
   1.575 +    err_msg("About to decrement below 0: words " SIZE_FORMAT
   1.576 +            " is greater than _allocated_capacity_words " SIZE_FORMAT,
   1.577 +            words, _allocated_capacity_words));
   1.578 +  _allocated_capacity_words = _allocated_capacity_words - words;
   1.579 +}
   1.580 +
   1.581 +void MetaspaceAux::inc_capacity(size_t words) {
   1.582 +  assert_lock_strong(SpaceManager::expand_lock());
   1.583 +  // Needs to be atomic
   1.584 +  _allocated_capacity_words = _allocated_capacity_words + words;
   1.585 +}
   1.586 +
   1.587 +void MetaspaceAux::dec_used(size_t words) {
   1.588 +  assert(words <= _allocated_used_words,
   1.589 +    err_msg("About to decrement below 0: words " SIZE_FORMAT
   1.590 +            " is greater than _allocated_used_words " SIZE_FORMAT,
   1.591 +            words, _allocated_used_words));
   1.592 +  // For CMS deallocation of the Metaspaces occurs during the
   1.593 +  // sweep which is a concurrent phase.  Protection by the expand_lock()
   1.594 +  // is not enough since allocation is on a per Metaspace basis
   1.595 +  // and protected by the Metaspace lock.
   1.596 +  jlong minus_words = (jlong) - (jlong) words;
   1.597 +  Atomic::add_ptr(minus_words, &_allocated_used_words);
   1.598 +}
   1.599 +
   1.600 +void MetaspaceAux::inc_used(size_t words) {
   1.601 +  // _allocated_used_words tracks allocations for
   1.602 +  // each piece of metadata.  Those allocations are
   1.603 +  // generally done concurrently by different application
   1.604 +  // threads so must be done atomically.
   1.605 +  Atomic::add_ptr(words, &_allocated_used_words);
   1.606 +}
   1.607 +
   1.608 +size_t MetaspaceAux::used_bytes_slow(Metaspace::MetadataType mdtype) {
   1.609    size_t used = 0;
   1.610    ClassLoaderDataGraphMetaspaceIterator iter;
   1.611    while (iter.repeat()) {
   1.612      Metaspace* msp = iter.get_next();
   1.613 -    // Sum allocation_total for each metaspace
   1.614 +    // Sum allocated_blocks_words for each metaspace
   1.615      if (msp != NULL) {
   1.616 -      used += msp->used_words(mdtype);
   1.617 +      used += msp->used_words_slow(mdtype);
   1.618      }
   1.619    }
   1.620    return used * BytesPerWord;
   1.621 @@ -2453,13 +2545,15 @@
   1.622    return free * BytesPerWord;
   1.623  }
   1.624  
   1.625 -size_t MetaspaceAux::capacity_in_bytes(Metaspace::MetadataType mdtype) {
   1.626 -  size_t capacity = free_chunks_total(mdtype);
   1.627 +size_t MetaspaceAux::capacity_bytes_slow(Metaspace::MetadataType mdtype) {
   1.628 +  // Don't count the space in the freelists.  That space will be
   1.629 +  // added to the capacity calculation as needed.
   1.630 +  size_t capacity = 0;
   1.631    ClassLoaderDataGraphMetaspaceIterator iter;
   1.632    while (iter.repeat()) {
   1.633      Metaspace* msp = iter.get_next();
   1.634      if (msp != NULL) {
   1.635 -      capacity += msp->capacity_words(mdtype);
   1.636 +      capacity += msp->capacity_words_slow(mdtype);
   1.637      }
   1.638    }
   1.639    return capacity * BytesPerWord;
   1.640 @@ -2486,23 +2580,30 @@
   1.641    return free_chunks_total(mdtype) * BytesPerWord;
   1.642  }
   1.643  
   1.644 +size_t MetaspaceAux::free_chunks_total() {
   1.645 +  return free_chunks_total(Metaspace::ClassType) +
   1.646 +         free_chunks_total(Metaspace::NonClassType);
   1.647 +}
   1.648 +
   1.649 +size_t MetaspaceAux::free_chunks_total_in_bytes() {
   1.650 +  return free_chunks_total() * BytesPerWord;
   1.651 +}
   1.652 +
   1.653  void MetaspaceAux::print_metaspace_change(size_t prev_metadata_used) {
   1.654    gclog_or_tty->print(", [Metaspace:");
   1.655    if (PrintGCDetails && Verbose) {
   1.656      gclog_or_tty->print(" "  SIZE_FORMAT
   1.657                          "->" SIZE_FORMAT
   1.658 -                        "("  SIZE_FORMAT "/" SIZE_FORMAT ")",
   1.659 +                        "("  SIZE_FORMAT ")",
   1.660                          prev_metadata_used,
   1.661 -                        used_in_bytes(),
   1.662 -                        capacity_in_bytes(),
   1.663 +                        allocated_capacity_bytes(),
   1.664                          reserved_in_bytes());
   1.665    } else {
   1.666      gclog_or_tty->print(" "  SIZE_FORMAT "K"
   1.667                          "->" SIZE_FORMAT "K"
   1.668 -                        "("  SIZE_FORMAT "K/" SIZE_FORMAT "K)",
   1.669 +                        "("  SIZE_FORMAT "K)",
   1.670                          prev_metadata_used / K,
   1.671 -                        used_in_bytes()/ K,
   1.672 -                        capacity_in_bytes()/K,
   1.673 +                        allocated_capacity_bytes() / K,
   1.674                          reserved_in_bytes()/ K);
   1.675    }
   1.676  
   1.677 @@ -2517,23 +2618,30 @@
   1.678    out->print_cr(" Metaspace total "
   1.679                  SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
   1.680                  " reserved " SIZE_FORMAT "K",
   1.681 -                capacity_in_bytes()/K, used_in_bytes()/K, reserved_in_bytes()/K);
   1.682 -  out->print_cr("  data space     "
   1.683 -                SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
   1.684 -                " reserved " SIZE_FORMAT "K",
   1.685 -                capacity_in_bytes(nct)/K, used_in_bytes(nct)/K, reserved_in_bytes(nct)/K);
   1.686 -  out->print_cr("  class space    "
   1.687 -                SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
   1.688 -                " reserved " SIZE_FORMAT "K",
   1.689 -                capacity_in_bytes(ct)/K, used_in_bytes(ct)/K, reserved_in_bytes(ct)/K);
   1.690 +                allocated_capacity_bytes()/K, allocated_used_bytes()/K, reserved_in_bytes()/K);
   1.691 +#if 0
   1.692 +// The calls to capacity_bytes_slow() and used_bytes_slow() cause
   1.693 +// lock ordering assertion failures with some collectors.  Do
   1.694 +// not include this code until the lock ordering is fixed.
   1.695 +  if (PrintGCDetails && Verbose) {
   1.696 +    out->print_cr("  data space     "
   1.697 +                  SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
   1.698 +                  " reserved " SIZE_FORMAT "K",
   1.699 +                  capacity_bytes_slow(nct)/K, used_bytes_slow(nct)/K, reserved_in_bytes(nct)/K);
   1.700 +    out->print_cr("  class space    "
   1.701 +                  SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
   1.702 +                  " reserved " SIZE_FORMAT "K",
   1.703 +                  capacity_bytes_slow(ct)/K, used_bytes_slow(ct)/K, reserved_in_bytes(ct)/K);
   1.704 +  }
   1.705 +#endif
   1.706  }
   1.707  
   1.708  // Print information for class space and data space separately.
   1.709  // This is almost the same as above.
   1.710  void MetaspaceAux::print_on(outputStream* out, Metaspace::MetadataType mdtype) {
   1.711    size_t free_chunks_capacity_bytes = free_chunks_total_in_bytes(mdtype);
   1.712 -  size_t capacity_bytes = capacity_in_bytes(mdtype);
   1.713 -  size_t used_bytes = used_in_bytes(mdtype);
   1.714 +  size_t capacity_bytes = capacity_bytes_slow(mdtype);
   1.715 +  size_t used_bytes = used_bytes_slow(mdtype);
   1.716    size_t free_bytes = free_in_bytes(mdtype);
   1.717    size_t used_and_free = used_bytes + free_bytes +
   1.718                             free_chunks_capacity_bytes;
   1.719 @@ -2606,6 +2714,36 @@
   1.720    Metaspace::class_space_list()->chunk_manager()->verify();
   1.721  }
   1.722  
   1.723 +void MetaspaceAux::verify_capacity() {
   1.724 +#ifdef ASSERT
   1.725 +  size_t running_sum_capacity_bytes = allocated_capacity_bytes();
   1.726 +  // For purposes of the running sum of used, verify against capacity
   1.727 +  size_t capacity_in_use_bytes = capacity_bytes_slow();
   1.728 +  assert(running_sum_capacity_bytes == capacity_in_use_bytes,
   1.729 +    err_msg("allocated_capacity_words() * BytesPerWord " SIZE_FORMAT
   1.730 +            " capacity_bytes_slow()" SIZE_FORMAT,
   1.731 +            running_sum_capacity_bytes, capacity_in_use_bytes));
   1.732 +#endif
   1.733 +}
   1.734 +
   1.735 +void MetaspaceAux::verify_used() {
   1.736 +#ifdef ASSERT
   1.737 +  size_t running_sum_used_bytes = allocated_used_bytes();
   1.738 +  // For purposes of the running sum of used, verify against capacity
   1.739 +  size_t used_in_use_bytes = used_bytes_slow();
   1.740 +  assert(allocated_used_bytes() == used_in_use_bytes,
   1.741 +    err_msg("allocated_used_bytes() " SIZE_FORMAT
   1.742 +            " used_bytes_slow()()" SIZE_FORMAT,
   1.743 +            allocated_used_bytes(), used_in_use_bytes));
   1.744 +#endif
   1.745 +}
   1.746 +
   1.747 +void MetaspaceAux::verify_metrics() {
   1.748 +  verify_capacity();
   1.749 +  verify_used();
   1.750 +}
   1.751 +
   1.752 +
   1.753  // Metaspace methods
   1.754  
   1.755  size_t Metaspace::_first_chunk_word_size = 0;
   1.756 @@ -2755,8 +2893,8 @@
   1.757    MetaWord* result;
   1.758    MetaspaceGC::set_expand_after_GC(true);
   1.759    size_t before_inc = MetaspaceGC::capacity_until_GC();
   1.760 -  size_t delta_words = MetaspaceGC::delta_capacity_until_GC(word_size);
   1.761 -  MetaspaceGC::inc_capacity_until_GC(delta_words);
   1.762 +  size_t delta_bytes = MetaspaceGC::delta_capacity_until_GC(word_size) * BytesPerWord;
   1.763 +  MetaspaceGC::inc_capacity_until_GC(delta_bytes);
   1.764    if (PrintGCDetails && Verbose) {
   1.765      gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT
   1.766        " to " SIZE_FORMAT, before_inc, MetaspaceGC::capacity_until_GC());
   1.767 @@ -2774,8 +2912,8 @@
   1.768    return (char*)vsm()->current_chunk()->bottom();
   1.769  }
   1.770  
   1.771 -size_t Metaspace::used_words(MetadataType mdtype) const {
   1.772 -  // return vsm()->allocation_total();
   1.773 +size_t Metaspace::used_words_slow(MetadataType mdtype) const {
   1.774 +  // return vsm()->allocated_used_words();
   1.775    return mdtype == ClassType ? class_vsm()->sum_used_in_chunks_in_use() :
   1.776                                 vsm()->sum_used_in_chunks_in_use();  // includes overhead!
   1.777  }
   1.778 @@ -2790,11 +2928,19 @@
   1.779  // have been made. Don't include space in the global freelist and
   1.780  // in the space available in the dictionary which
   1.781  // is already counted in some chunk.
   1.782 -size_t Metaspace::capacity_words(MetadataType mdtype) const {
   1.783 +size_t Metaspace::capacity_words_slow(MetadataType mdtype) const {
   1.784    return mdtype == ClassType ? class_vsm()->sum_capacity_in_chunks_in_use() :
   1.785                                 vsm()->sum_capacity_in_chunks_in_use();
   1.786  }
   1.787  
   1.788 +size_t Metaspace::used_bytes_slow(MetadataType mdtype) const {
   1.789 +  return used_words_slow(mdtype) * BytesPerWord;
   1.790 +}
   1.791 +
   1.792 +size_t Metaspace::capacity_bytes_slow(MetadataType mdtype) const {
   1.793 +  return capacity_words_slow(mdtype) * BytesPerWord;
   1.794 +}
   1.795 +
   1.796  void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
   1.797    if (SafepointSynchronize::is_at_safepoint()) {
   1.798      assert(Thread::current()->is_VM_thread(), "should be the VM thread");
   1.799 @@ -2921,10 +3067,6 @@
   1.800  }
   1.801  
   1.802  void Metaspace::dump(outputStream* const out) const {
   1.803 -  if (UseMallocOnly) {
   1.804 -    // Just print usage for now
   1.805 -    out->print_cr("usage %d", used_words(Metaspace::NonClassType));
   1.806 -  }
   1.807    out->print_cr("\nVirtual space manager: " INTPTR_FORMAT, vsm());
   1.808    vsm()->dump(out);
   1.809    out->print_cr("\nClass space manager: " INTPTR_FORMAT, class_vsm());

mercurial