src/share/vm/memory/metaspace.cpp

Print this page
rev 7106 : 8049599: MetaspaceGC::_capacity_until_GC can overflow (01)


1398     // allocation so make the delta greater than just enough
1399     // for this allocation.
1400     delta = max_delta;
1401   } else {
1402     // This allocation is large but the next ones are probably not
1403     // so increase by the minimum.
1404     delta = delta + min_delta;
1405   }
1406 
1407   assert_is_size_aligned(delta, Metaspace::commit_alignment());
1408 
1409   return delta;
1410 }
1411 
1412 size_t MetaspaceGC::capacity_until_GC() {
1413   size_t value = (size_t)OrderAccess::load_ptr_acquire(&_capacity_until_GC);
1414   assert(value >= MetaspaceSize, "Not initialied properly?");
1415   return value;
1416 }
1417 
1418 size_t MetaspaceGC::inc_capacity_until_GC(size_t v) {
1419   assert_is_size_aligned(v, Metaspace::commit_alignment());
1420 
1421   size_t capacity_until_GC = (size_t) _capacity_until_GC;
1422   size_t new_value = capacity_until_GC + v;
1423 
1424   if (new_value < capacity_until_GC) {
1425     // the addition wrapped around, set new_value to max value
1426     new_value = max_uintx;
1427   }
1428 
1429   bool cas_succeeded = false;
1430   size_t num_retries = 5; // just to limit the number of CAS attempts
1431   for (size_t i = 0; i < num_retries; i++) {
1432     intptr_t cmp = (intptr_t) capacity_until_GC;
1433     intptr_t swap = (intptr_t) new_value;
1434     intptr_t prev = Atomic::cmpxchg_ptr(swap, &_capacity_until_GC, cmp);
1435 
1436     if (prev == cmp) {
1437       cas_succeeded = true;
1438       break;
1439     }
1440   }
1441 
1442   // if the CAS did not succeed, just return the current value
1443   return cas_succeeded ? new_value : _capacity_until_GC;





1444 }
1445 
1446 size_t MetaspaceGC::dec_capacity_until_GC(size_t v) {
1447   assert_is_size_aligned(v, Metaspace::commit_alignment());
1448 
1449   return (size_t)Atomic::add_ptr(-(intptr_t)v, &_capacity_until_GC);
1450 }
1451 
1452 void MetaspaceGC::initialize() {
1453   // Set the high-water mark to MaxMetapaceSize during VM initializaton since
1454   // we can't do a GC during initialization.
1455   _capacity_until_GC = MaxMetaspaceSize;
1456 }
1457 
1458 void MetaspaceGC::post_initialize() {
1459   // Reset the high-water mark once the VM initialization is done.
1460   _capacity_until_GC = MAX2(MetaspaceAux::committed_bytes(), MetaspaceSize);
1461 }
1462 
1463 bool MetaspaceGC::can_expand(size_t word_size, bool is_class) {


1523     gclog_or_tty->print_cr("\nMetaspaceGC::compute_new_size: ");
1524     gclog_or_tty->print_cr("  "
1525                   "  minimum_free_percentage: %6.2f"
1526                   "  maximum_used_percentage: %6.2f",
1527                   minimum_free_percentage,
1528                   maximum_used_percentage);
1529     gclog_or_tty->print_cr("  "
1530                   "   used_after_gc       : %6.1fKB",
1531                   used_after_gc / (double) K);
1532   }
1533 
1534 
1535   size_t shrink_bytes = 0;
1536   if (capacity_until_GC < minimum_desired_capacity) {
1537     // If we have less capacity below the metaspace HWM, then
1538     // increment the HWM.
1539     size_t expand_bytes = minimum_desired_capacity - capacity_until_GC;
1540     expand_bytes = align_size_up(expand_bytes, Metaspace::commit_alignment());
1541     // Don't expand unless it's significant
1542     if (expand_bytes >= MinMetaspaceExpansion) {
1543       size_t new_capacity_until_GC = MetaspaceGC::inc_capacity_until_GC(expand_bytes);



1544       Metaspace::tracer()->report_gc_threshold(capacity_until_GC,
1545                                                new_capacity_until_GC,
1546                                                MetaspaceGCThresholdUpdater::ComputeNewSize);
1547       if (PrintGCDetails && Verbose) {
1548         gclog_or_tty->print_cr("    expanding:"
1549                       "  minimum_desired_capacity: %6.1fKB"
1550                       "  expand_bytes: %6.1fKB"
1551                       "  MinMetaspaceExpansion: %6.1fKB"
1552                       "  new metaspace HWM:  %6.1fKB",
1553                       minimum_desired_capacity / (double) K,
1554                       expand_bytes / (double) K,
1555                       MinMetaspaceExpansion / (double) K,
1556                       new_capacity_until_GC / (double) K);
1557       }
1558     }
1559     return;
1560   }
1561 
1562   // No expansion, now see if we want to shrink
1563   // We would never want to shrink more than this


3326 
3327 size_t Metaspace::align_word_size_up(size_t word_size) {
3328   size_t byte_size = word_size * wordSize;
3329   return ReservedSpace::allocation_align_size_up(byte_size) / wordSize;
3330 }
3331 
3332 MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) {
3333   // DumpSharedSpaces doesn't use class metadata area (yet)
3334   // Also, don't use class_vsm() unless UseCompressedClassPointers is true.
3335   if (is_class_space_allocation(mdtype)) {
3336     return  class_vsm()->allocate(word_size);
3337   } else {
3338     return  vsm()->allocate(word_size);
3339   }
3340 }
3341 
3342 MetaWord* Metaspace::expand_and_allocate(size_t word_size, MetadataType mdtype) {
3343   size_t delta_bytes = MetaspaceGC::delta_capacity_until_GC(word_size * BytesPerWord);
3344   assert(delta_bytes > 0, "Must be");
3345 
3346   size_t after_inc = MetaspaceGC::inc_capacity_until_GC(delta_bytes);
3347 
3348   // capacity_until_GC might be updated concurrently, must calculate previous value.
3349   size_t before_inc = after_inc - delta_bytes;







3350 

3351   tracer()->report_gc_threshold(before_inc, after_inc,
3352                                 MetaspaceGCThresholdUpdater::ExpandAndAllocate);
3353   if (PrintGCDetails && Verbose) {
3354     gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT
3355         " to " SIZE_FORMAT, before_inc, after_inc);
3356   }

3357 
3358   return allocate(word_size, mdtype);
3359 }
3360 
3361 // Space allocated in the Metaspace.  This may
3362 // be across several metadata virtual spaces.
3363 char* Metaspace::bottom() const {
3364   assert(DumpSharedSpaces, "only useful and valid for dumping shared spaces");
3365   return (char*)vsm()->current_chunk()->bottom();
3366 }
3367 
3368 size_t Metaspace::used_words_slow(MetadataType mdtype) const {
3369   if (mdtype == ClassType) {
3370     return using_class_space() ? class_vsm()->sum_used_in_chunks_in_use() : 0;
3371   } else {
3372     return vsm()->sum_used_in_chunks_in_use();  // includes overhead!
3373   }
3374 }
3375 
3376 size_t Metaspace::free_words_slow(MetadataType mdtype) const {
3377   if (mdtype == ClassType) {
3378     return using_class_space() ? class_vsm()->sum_free_in_chunks_in_use() : 0;




1398     // allocation so make the delta greater than just enough
1399     // for this allocation.
1400     delta = max_delta;
1401   } else {
1402     // This allocation is large but the next ones are probably not
1403     // so increase by the minimum.
1404     delta = delta + min_delta;
1405   }
1406 
1407   assert_is_size_aligned(delta, Metaspace::commit_alignment());
1408 
1409   return delta;
1410 }
1411 
1412 size_t MetaspaceGC::capacity_until_GC() {
1413   size_t value = (size_t)OrderAccess::load_ptr_acquire(&_capacity_until_GC);
1414   assert(value >= MetaspaceSize, "Not initialied properly?");
1415   return value;
1416 }
1417 
1418 bool MetaspaceGC::inc_capacity_until_GC(size_t v, size_t* new_cap_until_GC, size_t* old_cap_until_GC) {
1419   assert_is_size_aligned(v, Metaspace::commit_alignment());
1420 
1421   size_t capacity_until_GC = (size_t) _capacity_until_GC;
1422   size_t new_value = capacity_until_GC + v;
1423 
1424   if (new_value < capacity_until_GC) {
1425     // the addition wrapped around, set new_value to aligned max value
1426     new_value = align_size_down(max_uintx, Metaspace::commit_alignment());
1427   }
1428 
1429   intptr_t expected = (intptr_t) capacity_until_GC;
1430   intptr_t actual = Atomic::cmpxchg((intptr_t) new_value, &_capacity_until_GC, expected);




1431 
1432   if (expected != actual) {
1433     return false;


1434   }
1435 
1436   if (new_cap_until_GC != NULL) {
1437     *new_cap_until_GC = new_value;
1438   }
1439   if (old_cap_until_GC != NULL) {
1440     *old_cap_until_GC = capacity_until_GC;
1441   }
1442   return true;
1443 }
1444 
1445 size_t MetaspaceGC::dec_capacity_until_GC(size_t v) {
1446   assert_is_size_aligned(v, Metaspace::commit_alignment());
1447 
1448   return (size_t)Atomic::add_ptr(-(intptr_t)v, &_capacity_until_GC);
1449 }
1450 
1451 void MetaspaceGC::initialize() {
1452   // Set the high-water mark to MaxMetapaceSize during VM initializaton since
1453   // we can't do a GC during initialization.
1454   _capacity_until_GC = MaxMetaspaceSize;
1455 }
1456 
1457 void MetaspaceGC::post_initialize() {
1458   // Reset the high-water mark once the VM initialization is done.
1459   _capacity_until_GC = MAX2(MetaspaceAux::committed_bytes(), MetaspaceSize);
1460 }
1461 
1462 bool MetaspaceGC::can_expand(size_t word_size, bool is_class) {


1522     gclog_or_tty->print_cr("\nMetaspaceGC::compute_new_size: ");
1523     gclog_or_tty->print_cr("  "
1524                   "  minimum_free_percentage: %6.2f"
1525                   "  maximum_used_percentage: %6.2f",
1526                   minimum_free_percentage,
1527                   maximum_used_percentage);
1528     gclog_or_tty->print_cr("  "
1529                   "   used_after_gc       : %6.1fKB",
1530                   used_after_gc / (double) K);
1531   }
1532 
1533 
1534   size_t shrink_bytes = 0;
1535   if (capacity_until_GC < minimum_desired_capacity) {
1536     // If we have less capacity below the metaspace HWM, then
1537     // increment the HWM.
1538     size_t expand_bytes = minimum_desired_capacity - capacity_until_GC;
1539     expand_bytes = align_size_up(expand_bytes, Metaspace::commit_alignment());
1540     // Don't expand unless it's significant
1541     if (expand_bytes >= MinMetaspaceExpansion) {
1542       size_t new_capacity_until_GC = 0;
1543       bool succeeded = MetaspaceGC::inc_capacity_until_GC(expand_bytes, &new_capacity_until_GC);
1544       assert(succeeded, "Should always succesfully increment HWM when at safepoint");
1545 
1546       Metaspace::tracer()->report_gc_threshold(capacity_until_GC,
1547                                                new_capacity_until_GC,
1548                                                MetaspaceGCThresholdUpdater::ComputeNewSize);
1549       if (PrintGCDetails && Verbose) {
1550         gclog_or_tty->print_cr("    expanding:"
1551                       "  minimum_desired_capacity: %6.1fKB"
1552                       "  expand_bytes: %6.1fKB"
1553                       "  MinMetaspaceExpansion: %6.1fKB"
1554                       "  new metaspace HWM:  %6.1fKB",
1555                       minimum_desired_capacity / (double) K,
1556                       expand_bytes / (double) K,
1557                       MinMetaspaceExpansion / (double) K,
1558                       new_capacity_until_GC / (double) K);
1559       }
1560     }
1561     return;
1562   }
1563 
1564   // No expansion, now see if we want to shrink
1565   // We would never want to shrink more than this


3328 
3329 size_t Metaspace::align_word_size_up(size_t word_size) {
3330   size_t byte_size = word_size * wordSize;
3331   return ReservedSpace::allocation_align_size_up(byte_size) / wordSize;
3332 }
3333 
3334 MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) {
3335   // DumpSharedSpaces doesn't use class metadata area (yet)
3336   // Also, don't use class_vsm() unless UseCompressedClassPointers is true.
3337   if (is_class_space_allocation(mdtype)) {
3338     return  class_vsm()->allocate(word_size);
3339   } else {
3340     return  vsm()->allocate(word_size);
3341   }
3342 }
3343 
3344 MetaWord* Metaspace::expand_and_allocate(size_t word_size, MetadataType mdtype) {
3345   size_t delta_bytes = MetaspaceGC::delta_capacity_until_GC(word_size * BytesPerWord);
3346   assert(delta_bytes > 0, "Must be");
3347 
3348   size_t before_inc = 0;
3349   size_t after_inc = 0;
3350   MetaWord* res = NULL;
3351   bool inc_succeeded = false;
3352 
3353   while (!inc_succeeded && res == NULL) {
3354     inc_succeeded = MetaspaceGC::inc_capacity_until_GC(delta_bytes,
3355                                                        &after_inc,
3356                                                        &before_inc);
3357     res = allocate(word_size, mdtype);
3358   }
3359 
3360   if (inc_succeeded) {
3361     tracer()->report_gc_threshold(before_inc, after_inc,
3362                                   MetaspaceGCThresholdUpdater::ExpandAndAllocate);
3363     if (PrintGCDetails && Verbose) {
3364       gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT
3365           " to " SIZE_FORMAT, before_inc, after_inc);
3366     }
3367   }
3368 
3369   return res;
3370 }
3371 
3372 // Space allocated in the Metaspace.  This may
3373 // be across several metadata virtual spaces.
3374 char* Metaspace::bottom() const {
3375   assert(DumpSharedSpaces, "only useful and valid for dumping shared spaces");
3376   return (char*)vsm()->current_chunk()->bottom();
3377 }
3378 
3379 size_t Metaspace::used_words_slow(MetadataType mdtype) const {
3380   if (mdtype == ClassType) {
3381     return using_class_space() ? class_vsm()->sum_used_in_chunks_in_use() : 0;
3382   } else {
3383     return vsm()->sum_used_in_chunks_in_use();  // includes overhead!
3384   }
3385 }
3386 
3387 size_t Metaspace::free_words_slow(MetadataType mdtype) const {
3388   if (mdtype == ClassType) {
3389     return using_class_space() ? class_vsm()->sum_free_in_chunks_in_use() : 0;