8217432: MetaspaceGC::_capacity_until_GC exceeds MaxMetaspaceSize
Reviewed-by: tschatzl, stuefe
--- a/src/hotspot/share/memory/metaspace.cpp Fri Feb 01 06:42:41 2019 -0500
+++ b/src/hotspot/share/memory/metaspace.cpp Fri Feb 01 21:43:37 2019 +0900
@@ -132,7 +132,15 @@
return value;
}
-bool MetaspaceGC::inc_capacity_until_GC(size_t v, size_t* new_cap_until_GC, size_t* old_cap_until_GC) {
+// 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_aligned(v, Metaspace::commit_alignment());
size_t old_capacity_until_GC = _capacity_until_GC;
@@ -143,6 +151,16 @@
new_value = align_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;
+ }
size_t prev_value = Atomic::cmpxchg(new_value, &_capacity_until_GC, old_capacity_until_GC);
if (old_capacity_until_GC != prev_value) {
@@ -236,7 +254,7 @@
const double min_tmp = used_after_gc / maximum_used_percentage;
size_t minimum_desired_capacity =
- (size_t)MIN2(min_tmp, double(max_uintx));
+ (size_t)MIN2(min_tmp, double(MaxMetaspaceSize));
// Don't shrink less than the initial generation size
minimum_desired_capacity = MAX2(minimum_desired_capacity,
MetaspaceSize);
@@ -283,7 +301,7 @@
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));
+ size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(MaxMetaspaceSize));
maximum_desired_capacity = MAX2(maximum_desired_capacity,
MetaspaceSize);
log_trace(gc, metaspace)(" maximum_free_percentage: %6.2f minimum_used_percentage: %6.2f",
@@ -1470,6 +1488,7 @@
size_t before = 0;
size_t after = 0;
+ bool can_retry = true;
MetaWord* res;
bool incremented;
@@ -1477,9 +1496,9 @@
// 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);
+ incremented = MetaspaceGC::inc_capacity_until_GC(delta_bytes, &after, &before, &can_retry);
res = allocate(word_size, mdtype);
- } while (!incremented && res == NULL);
+ } while (!incremented && res == NULL && can_retry);
if (incremented) {
Metaspace::tracer()->report_gc_threshold(before, after,
--- a/src/hotspot/share/memory/metaspace.hpp Fri Feb 01 06:42:41 2019 -0500
+++ b/src/hotspot/share/memory/metaspace.hpp Fri Feb 01 21:43:37 2019 +0900
@@ -457,7 +457,8 @@
static size_t capacity_until_GC();
static bool inc_capacity_until_GC(size_t v,
size_t* new_cap_until_GC = NULL,
- size_t* old_cap_until_GC = NULL);
+ size_t* old_cap_until_GC = NULL,
+ bool* can_retry = NULL);
static size_t dec_capacity_until_GC(size_t v);
static bool should_concurrent_collect() { return _should_concurrent_collect; }
--- a/test/hotspot/jtreg/vmTestbase/metaspace/shrink_grow/ShrinkGrowTest/ShrinkGrowTest.java Fri Feb 01 06:42:41 2019 -0500
+++ b/test/hotspot/jtreg/vmTestbase/metaspace/shrink_grow/ShrinkGrowTest/ShrinkGrowTest.java Fri Feb 01 21:43:37 2019 +0900
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -25,6 +25,7 @@
/*
* @test
*
+ * @bug 8217432
* @summary converted from VM Testbase metaspace/shrink_grow/ShrinkGrowTest.
*
* @requires vm.opt.final.ClassUnloading