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());