This is an automated email from the ASF dual-hosted git repository.
junegunn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/master by this push:
new a699d303288 HBASE-15625 Make minimum free heap memory percentage
configurable (#7076)
a699d303288 is described below
commit a699d3032887cec9c39868dd93aa7ba84a9b8e03
Author: JinHyuk Kim <[email protected]>
AuthorDate: Wed Jul 30 10:05:07 2025 +0900
HBASE-15625 Make minimum free heap memory percentage configurable (#7076)
Signed-off-by: Junegunn Choi <[email protected]>
---
.../java/org/apache/hadoop/hbase/HConstants.java | 3 +-
hbase-common/src/main/resources/hbase-default.xml | 9 +++
.../hadoop/hbase/io/util/MemorySizeUtil.java | 91 ++++++++++++++++------
.../hadoop/hbase/regionserver/HRegionServer.java | 2 +-
.../hbase/regionserver/HeapMemoryManager.java | 73 +++++++++--------
.../hadoop/hbase/io/util/TestMemorySizeUtil.java | 89 +++++++++++++++++++++
6 files changed, 208 insertions(+), 59 deletions(-)
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java
b/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java
index eba3eb657ea..29def997818 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java
@@ -1041,7 +1041,8 @@ public final class HConstants {
public static final boolean HFILE_PREAD_ALL_BYTES_ENABLED_DEFAULT = false;
/*
- * Minimum percentage of free heap necessary for a successful cluster
startup.
+ * Default minimum fraction (20%) of free heap required for RegionServer
startup, used only when
+ * 'hbase.regionserver.free.heap.min.memory.size' is not explicitly set.
*/
public static final float HBASE_CLUSTER_MINIMUM_MEMORY_THRESHOLD = 0.2f;
diff --git a/hbase-common/src/main/resources/hbase-default.xml
b/hbase-common/src/main/resources/hbase-default.xml
index ccb1b28f870..ab700587ffa 100644
--- a/hbase-common/src/main/resources/hbase-default.xml
+++ b/hbase-common/src/main/resources/hbase-default.xml
@@ -278,6 +278,15 @@ possible configurations would overwhelm and obscure the
important.
log rolling. Even a small value (2 or 3) will allow a region server
to ride over transient HDFS errors.</description>
</property>
+ <property>
+ <name>hbase.regionserver.free.heap.min.memory.size</name>
+ <value></value>
+ <description>Defines the minimum amount of heap memory that must remain
free for the RegionServer to start,
+ specified in bytes or human-readable formats like '512m' for megabytes
or '4g' for gigabytes.
+ If not set, the default is 20% of the total heap size. To disable the
check entirely,
+ set this value to 0. If the combined memory usage of memstore and block
cache
+ exceeds (total heap - this value), the RegionServer will fail to
start.</description>
+ </property>
<property>
<name>hbase.regionserver.global.memstore.size</name>
<value></value>
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/util/MemorySizeUtil.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/util/MemorySizeUtil.java
index fdeef4e5839..7ada303d293 100644
---
a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/util/MemorySizeUtil.java
+++
b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/util/MemorySizeUtil.java
@@ -51,9 +51,14 @@ public class MemorySizeUtil {
// Default lower water mark limit is 95% size of memstore size.
public static final float DEFAULT_MEMSTORE_SIZE_LOWER_LIMIT = 0.95f;
+ /**
+ * Configuration key for the absolute amount of heap memory that must remain
free for a
+ * RegionServer to start
+ */
+ public static final String HBASE_REGION_SERVER_FREE_HEAP_MIN_MEMORY_SIZE_KEY
=
+ "hbase.regionserver.free.heap.min.memory.size";
+
private static final Logger LOG =
LoggerFactory.getLogger(MemorySizeUtil.class);
- // a constant to convert a fraction to a percentage
- private static final int CONVERT_TO_PERCENTAGE = 100;
private static final String JVM_HEAP_EXCEPTION = "Got an exception while
attempting to read "
+ "information about the JVM heap. Please submit this log information in a
bug report and "
@@ -77,34 +82,70 @@ public class MemorySizeUtil {
}
/**
- * Checks whether we have enough heap memory left out after portion for
Memstore and Block cache.
- * We need atleast 20% of heap left out for other RS functions.
+ * Validates that heap allocations for MemStore and block cache do not
exceed the allowed limit,
+ * ensuring enough free heap remains for other RegionServer tasks.
+ * @param conf the configuration to validate
+ * @throws RuntimeException if the combined allocation exceeds the threshold
*/
- public static void checkForClusterFreeHeapMemoryLimit(Configuration conf) {
+ public static void validateRegionServerHeapMemoryAllocation(Configuration
conf) {
if (conf.get(MEMSTORE_SIZE_OLD_KEY) != null) {
LOG.warn(MEMSTORE_SIZE_OLD_KEY + " is deprecated by " +
MEMSTORE_SIZE_KEY);
}
- float globalMemstoreSize = getGlobalMemStoreHeapPercent(conf, false);
- int gml = (int) (globalMemstoreSize * CONVERT_TO_PERCENTAGE);
- float blockCacheUpperLimit = getBlockCacheHeapPercent(conf);
- int bcul = (int) (blockCacheUpperLimit * CONVERT_TO_PERCENTAGE);
- if (
- CONVERT_TO_PERCENTAGE - (gml + bcul)
- < (int) (CONVERT_TO_PERCENTAGE *
HConstants.HBASE_CLUSTER_MINIMUM_MEMORY_THRESHOLD)
- ) {
- throw new RuntimeException("Current heap configuration for MemStore and
BlockCache exceeds "
- + "the threshold required for successful cluster operation. "
- + "The combined value cannot exceed 0.8. Please check " + "the
settings for "
- + MEMSTORE_SIZE_KEY + " and either " +
HConstants.HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY + " or "
- + HConstants.HFILE_BLOCK_CACHE_SIZE_KEY + " in your configuration. " +
MEMSTORE_SIZE_KEY
- + "=" + globalMemstoreSize + ", " +
HConstants.HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY + "="
- + conf.get(HConstants.HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY) + ", "
- + HConstants.HFILE_BLOCK_CACHE_SIZE_KEY + "="
- + conf.get(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY) + ". (Note: If both "
- + HConstants.HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY + " and "
- + HConstants.HFILE_BLOCK_CACHE_SIZE_KEY + " are set, " + "the system
will use "
- + HConstants.HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY + ")");
+ float memStoreFraction = getGlobalMemStoreHeapPercent(conf, false);
+ float blockCacheFraction = getBlockCacheHeapPercent(conf);
+ float minFreeHeapFraction = getRegionServerMinFreeHeapFraction(conf);
+
+ int memStorePercent = (int) (memStoreFraction * 100);
+ int blockCachePercent = (int) (blockCacheFraction * 100);
+ int minFreeHeapPercent = (int) (minFreeHeapFraction * 100);
+ int usedPercent = memStorePercent + blockCachePercent;
+ int maxAllowedUsed = 100 - minFreeHeapPercent;
+
+ if (usedPercent > maxAllowedUsed) {
+ throw new RuntimeException(String.format(
+ "RegionServer heap memory allocation is invalid: total memory usage
exceeds 100%% "
+ + "(memStore + blockCache + requiredFreeHeap). "
+ + "Check the following configuration values:%n" + " - %s = %.2f%n"
+ " - %s = %s%n"
+ + " - %s = %s%n" + " - %s = %s",
+ MEMSTORE_SIZE_KEY, memStoreFraction,
HConstants.HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY,
+ conf.get(HConstants.HFILE_BLOCK_CACHE_MEMORY_SIZE_KEY),
+ HConstants.HFILE_BLOCK_CACHE_SIZE_KEY,
conf.get(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY),
+ HBASE_REGION_SERVER_FREE_HEAP_MIN_MEMORY_SIZE_KEY,
+ conf.get(HBASE_REGION_SERVER_FREE_HEAP_MIN_MEMORY_SIZE_KEY)));
+ }
+ }
+
+ /**
+ * Retrieve an explicit minimum required free heap size in bytes in the
configuration.
+ * @param conf used to read configs
+ * @return the minimum required free heap size in bytes, or a negative value
if not configured.
+ * @throws IllegalArgumentException if
HBASE_REGION_SERVER_FREE_HEAP_MIN_MEMORY_SIZE_KEY format is
+ * invalid
+ */
+ private static long getRegionServerMinFreeHeapInBytes(Configuration conf) {
+ final String key = HBASE_REGION_SERVER_FREE_HEAP_MIN_MEMORY_SIZE_KEY;
+ try {
+ return Long.parseLong(conf.get(key));
+ } catch (NumberFormatException e) {
+ return (long) conf.getStorageSize(key, -1, StorageUnit.BYTES);
+ }
+ }
+
+ /**
+ * Returns the minimum required free heap as a fraction of total heap.
+ */
+ public static float getRegionServerMinFreeHeapFraction(final Configuration
conf) {
+ final MemoryUsage usage = safeGetHeapMemoryUsage();
+ if (usage == null) {
+ return 0;
+ }
+
+ long minFreeHeapInBytes = getRegionServerMinFreeHeapInBytes(conf);
+ if (minFreeHeapInBytes >= 0) {
+ return (float) minFreeHeapInBytes / usage.getMax();
}
+
+ return HConstants.HBASE_CLUSTER_MINIMUM_MEMORY_THRESHOLD;
}
/**
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
index ae170ccad2a..2bddf7f9d27 100644
---
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
+++
b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
@@ -510,7 +510,7 @@ public class HRegionServer extends
HBaseServerBase<RSRpcServices>
try (Scope ignored = span.makeCurrent()) {
this.dataFsOk = true;
this.masterless = !clusterMode();
- MemorySizeUtil.checkForClusterFreeHeapMemoryLimit(this.conf);
+ MemorySizeUtil.validateRegionServerHeapMemoryAllocation(conf);
HFile.checkHFileVersion(this.conf);
checkCodecs(this.conf);
FSUtils.setupShortCircuitRead(this.conf);
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HeapMemoryManager.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HeapMemoryManager.java
index 1b28846efad..9c4cd5b3ca4 100644
---
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HeapMemoryManager.java
+++
b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HeapMemoryManager.java
@@ -47,8 +47,6 @@ import org.slf4j.LoggerFactory;
public class HeapMemoryManager {
private static final Logger LOG =
LoggerFactory.getLogger(HeapMemoryManager.class);
private static final int CONVERT_TO_PERCENTAGE = 100;
- private static final int CLUSTER_MINIMUM_MEMORY_THRESHOLD =
- (int) (CONVERT_TO_PERCENTAGE *
HConstants.HBASE_CLUSTER_MINIMUM_MEMORY_THRESHOLD);
public static final String BLOCK_CACHE_SIZE_MAX_RANGE_KEY =
"hfile.block.cache.size.max.range";
public static final String BLOCK_CACHE_SIZE_MIN_RANGE_KEY =
"hfile.block.cache.size.min.range";
@@ -84,6 +82,7 @@ public class HeapMemoryManager {
private final boolean tunerOn;
private final int defaultChorePeriod;
private final float heapOccupancyLowWatermark;
+ private final float minFreeHeapFraction;
private final long maxHeapSize;
{
@@ -110,6 +109,7 @@ public class HeapMemoryManager {
this.memStoreFlusher = memStoreFlusher;
this.server = server;
this.regionServerAccounting = regionServerAccounting;
+ this.minFreeHeapFraction =
MemorySizeUtil.getRegionServerMinFreeHeapFraction(conf);
this.tunerOn = doInit(conf);
this.defaultChorePeriod =
conf.getInt(HBASE_RS_HEAP_MEMORY_TUNER_PERIOD,
HBASE_RS_HEAP_MEMORY_TUNER_DEFAULT_PERIOD);
@@ -130,7 +130,7 @@ public class HeapMemoryManager {
boolean tuningEnabled = true;
globalMemStorePercent = MemorySizeUtil.getGlobalMemStoreHeapPercent(conf,
false);
blockCachePercent = MemorySizeUtil.getBlockCacheHeapPercent(conf);
- MemorySizeUtil.checkForClusterFreeHeapMemoryLimit(conf);
+ MemorySizeUtil.validateRegionServerHeapMemoryAllocation(conf);
// Initialize max and min range for memstore heap space
globalMemStorePercentMinRange =
conf.getFloat(MEMSTORE_SIZE_MIN_RANGE_KEY, globalMemStorePercent);
@@ -184,28 +184,11 @@ public class HeapMemoryManager {
tuningEnabled = false;
}
- int gml = (int) (globalMemStorePercentMaxRange * CONVERT_TO_PERCENTAGE);
- int bcul = (int) ((blockCachePercentMinRange) * CONVERT_TO_PERCENTAGE);
- if (CONVERT_TO_PERCENTAGE - (gml + bcul) <
CLUSTER_MINIMUM_MEMORY_THRESHOLD) {
- throw new RuntimeException("Current heap configuration for MemStore and
BlockCache exceeds "
- + "the threshold required for successful cluster operation. "
- + "The combined value cannot exceed 0.8. Please check the settings for
"
- + MEMSTORE_SIZE_MAX_RANGE_KEY + " and " +
BLOCK_CACHE_SIZE_MIN_RANGE_KEY
- + " in your configuration. " + MEMSTORE_SIZE_MAX_RANGE_KEY + " is "
- + globalMemStorePercentMaxRange + " and " +
BLOCK_CACHE_SIZE_MIN_RANGE_KEY + " is "
- + blockCachePercentMinRange);
- }
- gml = (int) (globalMemStorePercentMinRange * CONVERT_TO_PERCENTAGE);
- bcul = (int) ((blockCachePercentMaxRange) * CONVERT_TO_PERCENTAGE);
- if (CONVERT_TO_PERCENTAGE - (gml + bcul) <
CLUSTER_MINIMUM_MEMORY_THRESHOLD) {
- throw new RuntimeException("Current heap configuration for MemStore and
BlockCache exceeds "
- + "the threshold required for successful cluster operation. "
- + "The combined value cannot exceed 0.8. Please check the settings for
"
- + MEMSTORE_SIZE_MIN_RANGE_KEY + " and " +
BLOCK_CACHE_SIZE_MAX_RANGE_KEY
- + " in your configuration. " + MEMSTORE_SIZE_MIN_RANGE_KEY + " is "
- + globalMemStorePercentMinRange + " and " +
BLOCK_CACHE_SIZE_MAX_RANGE_KEY + " is "
- + blockCachePercentMaxRange);
- }
+ checkHeapMemoryLimits(MEMSTORE_SIZE_MAX_RANGE_KEY,
globalMemStorePercentMaxRange,
+ BLOCK_CACHE_SIZE_MIN_RANGE_KEY, blockCachePercentMinRange);
+ checkHeapMemoryLimits(MEMSTORE_SIZE_MIN_RANGE_KEY,
globalMemStorePercentMinRange,
+ BLOCK_CACHE_SIZE_MAX_RANGE_KEY, blockCachePercentMaxRange);
+
return tuningEnabled;
}
@@ -241,6 +224,31 @@ public class HeapMemoryManager {
: this.heapOccupancyPercent;
}
+ private boolean isHeapMemoryUsageExceedingLimit(float memStoreFraction,
+ float blockCacheFraction) {
+ // Use integer percentage to avoid subtle float precision issues and
ensure consistent
+ // comparison. This also maintains backward compatibility with previous
logic relying on int
+ // truncation.
+ int memStorePercent = (int) (memStoreFraction * CONVERT_TO_PERCENTAGE);
+ int blockCachePercent = (int) (blockCacheFraction * CONVERT_TO_PERCENTAGE);
+ int minFreeHeapPercent = (int) (this.minFreeHeapFraction *
CONVERT_TO_PERCENTAGE);
+
+ return memStorePercent + blockCachePercent + minFreeHeapPercent >
CONVERT_TO_PERCENTAGE;
+ }
+
+ private void checkHeapMemoryLimits(String memStoreConfKey, float
memStoreFraction,
+ String blockCacheConfKey, float blockCacheFraction) {
+ if (isHeapMemoryUsageExceedingLimit(memStoreFraction, blockCacheFraction))
{
+ throw new RuntimeException(String.format(
+ "Current heap configuration for MemStore and BlockCache exceeds the
allowed heap usage. "
+ + "At least %.2f of the heap must remain free to ensure stable
RegionServer operation. "
+ + "Please check the settings for %s and %s in your configuration. "
+ + "%s is %.2f and %s is %.2f",
+ minFreeHeapFraction, memStoreConfKey, blockCacheConfKey,
memStoreConfKey, memStoreFraction,
+ blockCacheConfKey, blockCacheFraction));
+ }
+ }
+
private class HeapMemoryTunerChore extends ScheduledChore implements
FlushRequestListener {
private HeapMemoryTuner heapMemTuner;
private AtomicLong blockedFlushCount = new AtomicLong();
@@ -363,14 +371,15 @@ public class HeapMemoryManager {
+ blockCachePercentMaxRange + ". Resetting blockCacheSize to min
size");
blockCacheSize = blockCachePercentMaxRange;
}
- int gml = (int) (memstoreSize * CONVERT_TO_PERCENTAGE);
- int bcul = (int) ((blockCacheSize) * CONVERT_TO_PERCENTAGE);
- if (CONVERT_TO_PERCENTAGE - (gml + bcul) <
CLUSTER_MINIMUM_MEMORY_THRESHOLD) {
+
+ if (isHeapMemoryUsageExceedingLimit(memstoreSize, blockCacheSize)) {
LOG.info("Current heap configuration from HeapMemoryTuner exceeds "
- + "the threshold required for successful cluster operation. "
- + "The combined value cannot exceed 0.8. " +
MemorySizeUtil.MEMSTORE_SIZE_KEY + " is "
- + memstoreSize + " and " + HFILE_BLOCK_CACHE_SIZE_KEY + " is " +
blockCacheSize);
- // TODO can adjust the value so as not exceed 80%. Is that correct?
may be.
+ + "the allowed heap usage. At least " + minFreeHeapFraction
+ + " of the heap must remain free to ensure stable RegionServer
operation. "
+ + MemorySizeUtil.MEMSTORE_SIZE_KEY + " is " + memstoreSize + " and
"
+ + HFILE_BLOCK_CACHE_SIZE_KEY + " is " + blockCacheSize);
+ // NOTE: In the future, we might adjust values to not exceed limits,
+ // but for now tuning is skipped if over threshold.
} else {
int memStoreDeltaSize =
(int) ((memstoreSize - globalMemStorePercent) *
CONVERT_TO_PERCENTAGE);
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/io/util/TestMemorySizeUtil.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/io/util/TestMemorySizeUtil.java
new file mode 100644
index 00000000000..5f00c34dbcb
--- /dev/null
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/io/util/TestMemorySizeUtil.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.io.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseClassTestRule;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.testclassification.MiscTests;
+import org.apache.hadoop.hbase.testclassification.SmallTests;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category({ MiscTests.class, SmallTests.class })
+public class TestMemorySizeUtil {
+
+ @ClassRule
+ public static final HBaseClassTestRule CLASS_RULE =
+ HBaseClassTestRule.forClass(TestMemorySizeUtil.class);
+
+ private Configuration conf;
+
+ @Before
+ public void setup() {
+ conf = new Configuration();
+ }
+
+ @Test
+ public void testValidateRegionServerHeapMemoryAllocation() {
+ // when memstore size + block cache size + default free heap min size ==
1.0
+ conf.setFloat(MemorySizeUtil.MEMSTORE_SIZE_KEY, 0.4f);
+ conf.setFloat(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY, 0.4f);
+ assertEquals(HConstants.HBASE_CLUSTER_MINIMUM_MEMORY_THRESHOLD, 0.2f,
0.0f);
+ MemorySizeUtil.validateRegionServerHeapMemoryAllocation(conf);
+
+ // when memstore size + block cache size + default free heap min size > 1.0
+ conf.setFloat(MemorySizeUtil.MEMSTORE_SIZE_KEY, 0.5f);
+ assertThrows(RuntimeException.class,
+ () -> MemorySizeUtil.validateRegionServerHeapMemoryAllocation(conf));
+
+ // when free heap min size is set to 0, it should not throw an exception
+ conf.setFloat(MemorySizeUtil.MEMSTORE_SIZE_KEY, 0.5f);
+ conf.setFloat(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY, 0.5f);
+
conf.setLong(MemorySizeUtil.HBASE_REGION_SERVER_FREE_HEAP_MIN_MEMORY_SIZE_KEY,
0L);
+ MemorySizeUtil.validateRegionServerHeapMemoryAllocation(conf);
+
+ // when free heap min size is set to a negative value, it should be
regarded as default value
+
conf.setLong(MemorySizeUtil.HBASE_REGION_SERVER_FREE_HEAP_MIN_MEMORY_SIZE_KEY,
-1024L);
+ conf.setFloat(MemorySizeUtil.MEMSTORE_SIZE_KEY, 0.4f);
+ conf.setFloat(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY, 0.4f);
+ MemorySizeUtil.validateRegionServerHeapMemoryAllocation(conf);
+
+ conf.setFloat(MemorySizeUtil.MEMSTORE_SIZE_KEY, 0.41f);
+ assertThrows(RuntimeException.class,
+ () -> MemorySizeUtil.validateRegionServerHeapMemoryAllocation(conf));
+ }
+
+ @Test
+ public void testGetRegionServerMinFreeHeapFraction() {
+ // when setting is not set, it should return the default value
+ conf.set(MemorySizeUtil.HBASE_REGION_SERVER_FREE_HEAP_MIN_MEMORY_SIZE_KEY,
"");
+ float minFreeHeapFraction =
MemorySizeUtil.getRegionServerMinFreeHeapFraction(conf);
+ assertEquals(HConstants.HBASE_CLUSTER_MINIMUM_MEMORY_THRESHOLD,
minFreeHeapFraction, 0.0f);
+
+ // when setting to 0, it should return 0.0f
+ conf.set(MemorySizeUtil.HBASE_REGION_SERVER_FREE_HEAP_MIN_MEMORY_SIZE_KEY,
"0");
+ minFreeHeapFraction =
MemorySizeUtil.getRegionServerMinFreeHeapFraction(conf);
+ assertEquals(0.0f, minFreeHeapFraction, 0.0f);
+ }
+}