< prev index next >

src/share/vm/memory/metaspace.cpp

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 1420,1440 **** size_t value = (size_t)OrderAccess::load_ptr_acquire(&_capacity_until_GC); assert(value >= MetaspaceSize, "Not initialied properly?"); return value; } ! bool MetaspaceGC::inc_capacity_until_GC(size_t v, size_t* new_cap_until_GC, size_t* old_cap_until_GC) { assert_is_size_aligned(v, Metaspace::commit_alignment()); size_t capacity_until_GC = (size_t) _capacity_until_GC; size_t new_value = capacity_until_GC + v; if (new_value < capacity_until_GC) { // The addition wrapped around, set new_value to aligned max value. new_value = align_size_down(max_uintx, Metaspace::commit_alignment()); } intptr_t expected = (intptr_t) capacity_until_GC; intptr_t actual = Atomic::cmpxchg_ptr((intptr_t) new_value, &_capacity_until_GC, expected); if (expected != actual) { return false; --- 1420,1459 ---- size_t value = (size_t)OrderAccess::load_ptr_acquire(&_capacity_until_GC); assert(value >= MetaspaceSize, "Not initialied properly?"); return value; } ! // Try to increase the _capacity_until_GC limit counter by v bytes. ! // Returns true if it succeeded. It may fail if either another thread ! // concurrently increased the limit or the new limit would be larger ! // than MaxMetaspaceSize. ! // On success, optionally returns new and old metaspace capacity in ! // new_cap_until_GC and old_cap_until_GC respectively. ! // On error, optionally sets can_retry to indicate whether if there is ! // actually enough space remaining to satisfy the request. ! bool MetaspaceGC::inc_capacity_until_GC(size_t v, size_t* new_cap_until_GC, size_t* old_cap_until_GC, bool* can_retry) { assert_is_size_aligned(v, Metaspace::commit_alignment()); size_t capacity_until_GC = (size_t) _capacity_until_GC; size_t new_value = capacity_until_GC + v; if (new_value < capacity_until_GC) { // The addition wrapped around, set new_value to aligned max value. new_value = align_size_down(max_uintx, Metaspace::commit_alignment()); } + if (new_value > MaxMetaspaceSize) { + if (can_retry != NULL) { + *can_retry = false; + } + return false; + } + + if (can_retry != NULL) { + *can_retry = true; + } + intptr_t expected = (intptr_t) capacity_until_GC; intptr_t actual = Atomic::cmpxchg_ptr((intptr_t) new_value, &_capacity_until_GC, expected); if (expected != actual) { return false;
*** 1518,1528 **** const double minimum_free_percentage = MinMetaspaceFreeRatio / 100.0; const double maximum_used_percentage = 1.0 - minimum_free_percentage; const double min_tmp = used_after_gc / maximum_used_percentage; size_t minimum_desired_capacity = ! (size_t)MIN2(min_tmp, double(max_uintx)); // Don't shrink less than the initial generation size minimum_desired_capacity = MAX2(minimum_desired_capacity, MetaspaceSize); if (PrintGCDetails && Verbose) { --- 1537,1547 ---- const double minimum_free_percentage = MinMetaspaceFreeRatio / 100.0; const double maximum_used_percentage = 1.0 - minimum_free_percentage; const double min_tmp = used_after_gc / maximum_used_percentage; size_t minimum_desired_capacity = ! (size_t)MIN2(min_tmp, double(MaxMetaspaceSize)); // Don't shrink less than the initial generation size minimum_desired_capacity = MAX2(minimum_desired_capacity, MetaspaceSize); if (PrintGCDetails && Verbose) {
*** 1577,1587 **** // Should shrinking be considered? if (MaxMetaspaceFreeRatio < 100) { const double maximum_free_percentage = MaxMetaspaceFreeRatio / 100.0; const double minimum_used_percentage = 1.0 - maximum_free_percentage; const double max_tmp = used_after_gc / minimum_used_percentage; ! size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(max_uintx)); maximum_desired_capacity = MAX2(maximum_desired_capacity, MetaspaceSize); if (PrintGCDetails && Verbose) { gclog_or_tty->print_cr(" " " maximum_free_percentage: %6.2f" --- 1596,1606 ---- // Should shrinking be considered? if (MaxMetaspaceFreeRatio < 100) { const double maximum_free_percentage = MaxMetaspaceFreeRatio / 100.0; const double minimum_used_percentage = 1.0 - maximum_free_percentage; const double max_tmp = used_after_gc / minimum_used_percentage; ! size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(MaxMetaspaceSize)); maximum_desired_capacity = MAX2(maximum_desired_capacity, MetaspaceSize); if (PrintGCDetails && Verbose) { gclog_or_tty->print_cr(" " " maximum_free_percentage: %6.2f"
*** 3406,3425 **** size_t delta_bytes = MetaspaceGC::delta_capacity_until_GC(word_size * BytesPerWord); assert(delta_bytes > 0, "Must be"); size_t before = 0; size_t after = 0; MetaWord* res; bool incremented; // Each thread increments the HWM at most once. Even if the thread fails to increment // the HWM, an allocation is still attempted. This is because another thread must then // have incremented the HWM and therefore the allocation might still succeed. do { ! incremented = MetaspaceGC::inc_capacity_until_GC(delta_bytes, &after, &before); res = allocate(word_size, mdtype); ! } while (!incremented && res == NULL); if (incremented) { tracer()->report_gc_threshold(before, after, MetaspaceGCThresholdUpdater::ExpandAndAllocate); if (PrintGCDetails && Verbose) { --- 3425,3445 ---- size_t delta_bytes = MetaspaceGC::delta_capacity_until_GC(word_size * BytesPerWord); assert(delta_bytes > 0, "Must be"); size_t before = 0; size_t after = 0; + bool can_retry = true; MetaWord* res; bool incremented; // Each thread increments the HWM at most once. Even if the thread fails to increment // the HWM, an allocation is still attempted. This is because another thread must then // have incremented the HWM and therefore the allocation might still succeed. do { ! incremented = MetaspaceGC::inc_capacity_until_GC(delta_bytes, &after, &before, &can_retry); res = allocate(word_size, mdtype); ! } while (!incremented && res == NULL && can_retry); if (incremented) { tracer()->report_gc_threshold(before, after, MetaspaceGCThresholdUpdater::ExpandAndAllocate); if (PrintGCDetails && Verbose) {
< prev index next >