This is an automated email from the ASF dual-hosted git repository.

ctubbsii pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo.git


The following commit(s) were added to refs/heads/main by this push:
     new a3444f7fda Fix MemoryStarved ITs (#4024)
a3444f7fda is described below

commit a3444f7fda056bed6e36f8b3bc6252abbe1807cb
Author: Christopher Tubbs <ctubb...@apache.org>
AuthorDate: Wed Dec 6 14:46:38 2023 -0500

    Fix MemoryStarved ITs (#4024)
    
    Rewrite MemoryConsumingIterator's method to compute the amount of memory
    to consume, so that:
    
    * The implementation is more comprehensible
    * Replace exception with bounds checking
    * Avoid allocating more than necessary (a single byte is sufficient)
    * The log message includes the amount of used memory detected
    * The waiting message appears, even when memory was allocated, because
      that's the behavior
    * Give the GC more time to detect the changed GC condition before trying
      to detect the low memory condition
    
    Also, remove hard-coded comments for size of heap and incorrect interval
    frequency, and increase the configured free memory threshold, so that
    the memory percentage isn't so low, it doesn't get lower than the
    minimum that G1GC needs to do its job by default on a 256K VM.
    
    This fixes #3868
    
    Also, trivially remove an unused Logger
---
 .../org/apache/accumulo/test/CloseScannerIT.java   |  4 ---
 .../test/functional/MemoryConsumingIterator.java   | 33 +++++++++-------------
 .../test/functional/MemoryStarvedMajCIT.java       |  2 --
 .../test/functional/MemoryStarvedMinCIT.java       |  2 --
 .../test/functional/MemoryStarvedScanIT.java       |  4 +--
 5 files changed, 14 insertions(+), 31 deletions(-)

diff --git a/test/src/main/java/org/apache/accumulo/test/CloseScannerIT.java 
b/test/src/main/java/org/apache/accumulo/test/CloseScannerIT.java
index 96b4b930c2..4dc89cac9a 100644
--- a/test/src/main/java/org/apache/accumulo/test/CloseScannerIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/CloseScannerIT.java
@@ -32,13 +32,9 @@ import org.apache.accumulo.harness.AccumuloClusterHarness;
 import org.apache.accumulo.test.functional.ReadWriteIT;
 import org.apache.accumulo.test.util.Wait;
 import org.junit.jupiter.api.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 public class CloseScannerIT extends AccumuloClusterHarness {
 
-  private static final Logger LOG = 
LoggerFactory.getLogger(CloseScannerIT.class);
-
   static final int ROWS = 1000;
   static final int COLS = 1000;
 
diff --git 
a/test/src/main/java/org/apache/accumulo/test/functional/MemoryConsumingIterator.java
 
b/test/src/main/java/org/apache/accumulo/test/functional/MemoryConsumingIterator.java
index 3b98f1c801..2b23fb1cff 100644
--- 
a/test/src/main/java/org/apache/accumulo/test/functional/MemoryConsumingIterator.java
+++ 
b/test/src/main/java/org/apache/accumulo/test/functional/MemoryConsumingIterator.java
@@ -39,8 +39,6 @@ public class MemoryConsumingIterator extends WrappingIterator 
{
 
   private static final List<byte[]> BUFFERS = new ArrayList<>();
 
-  private static final int TEN_MiB = 10 * 1024 * 1024;
-
   public static void freeBuffers() {
     BUFFERS.clear();
   }
@@ -50,23 +48,17 @@ public class MemoryConsumingIterator extends 
WrappingIterator {
     System.gc();
     Runtime runtime = Runtime.getRuntime();
     long maxConfiguredMemory = runtime.maxMemory();
-    long allocatedMemory = runtime.totalMemory();
-    long allocatedFreeMemory = runtime.freeMemory();
-    long freeMemory = maxConfiguredMemory - (allocatedMemory - 
allocatedFreeMemory);
-    long minimumFreeMemoryThreshold =
-        (long) (maxConfiguredMemory * 
MemoryStarvedScanIT.FREE_MEMORY_THRESHOLD);
+    long usedMemory = runtime.totalMemory() - runtime.freeMemory();
+    long freeMemory = maxConfiguredMemory - usedMemory;
+    long minFreeMemory = (long) (maxConfiguredMemory * 
MemoryStarvedScanIT.FREE_MEMORY_THRESHOLD);
 
-    int amountToConsume = 0;
-    if (freeMemory > minimumFreeMemoryThreshold) {
-      amountToConsume = (int) (freeMemory - (minimumFreeMemoryThreshold - 
TEN_MiB));
-    }
-    if (amountToConsume < 0) {
-      throw new IllegalStateException(
-          "Overflow. Unsupported memory size for tablet server when using this 
iterator");
-    }
-    LOG.info("max: {}, free: {}, minFree: {}, amountToConsume: {}", 
maxConfiguredMemory, freeMemory,
-        minimumFreeMemoryThreshold, amountToConsume);
-    return amountToConsume;
+    // consume free memory, and exceed the minimum threshold by just a little 
bit
+    // don't exceed typical JDK byte array limit
+    long amountToConsume =
+        Math.min(Math.max(0, freeMemory + 1 - minFreeMemory), 
Integer.MAX_VALUE - 8);
+    LOG.info("max: {}, used: {}, free: {}, minFree: {}, amountToConsume: {}", 
maxConfiguredMemory,
+        usedMemory, freeMemory, minFreeMemory, amountToConsume);
+    return (int) amountToConsume;
   }
 
   @Override
@@ -80,10 +72,11 @@ public class MemoryConsumingIterator extends 
WrappingIterator {
         BUFFERS.add(new byte[amountToConsume]);
         LOG.info("memory allocated");
       } else {
-        LOG.info("Waiting for LowMemoryDetector to recognize low on memory 
condition.");
+        LOG.info("consumed enough; no more memory allocated");
       }
+      LOG.info("Waiting for LowMemoryDetector to recognize low on memory 
condition.");
       try {
-        Thread.sleep(SECONDS.toMillis(1));
+        Thread.sleep(SECONDS.toMillis(5));
       } catch (InterruptedException ex) {
         Thread.currentThread().interrupt();
         throw new IOException("interrupted during sleep", ex);
diff --git 
a/test/src/main/java/org/apache/accumulo/test/functional/MemoryStarvedMajCIT.java
 
b/test/src/main/java/org/apache/accumulo/test/functional/MemoryStarvedMajCIT.java
index 366b62f935..771d74d588 100644
--- 
a/test/src/main/java/org/apache/accumulo/test/functional/MemoryStarvedMajCIT.java
+++ 
b/test/src/main/java/org/apache/accumulo/test/functional/MemoryStarvedMajCIT.java
@@ -58,8 +58,6 @@ public class MemoryStarvedMajCIT extends 
SharedMiniClusterBase {
       cfg.setNumTservers(1);
       cfg.setMemory(ServerType.TABLET_SERVER, 256, MemoryUnit.MEGABYTE);
       // Configure the LowMemoryDetector in the TabletServer
-      // check on 1s intervals and set low mem condition if more than 80% of
-      // the heap is used.
       cfg.setProperty(Property.GENERAL_LOW_MEM_DETECTOR_INTERVAL, "5s");
       cfg.setProperty(Property.GENERAL_LOW_MEM_DETECTOR_THRESHOLD,
           Double.toString(MemoryStarvedScanIT.FREE_MEMORY_THRESHOLD));
diff --git 
a/test/src/main/java/org/apache/accumulo/test/functional/MemoryStarvedMinCIT.java
 
b/test/src/main/java/org/apache/accumulo/test/functional/MemoryStarvedMinCIT.java
index 0a001047cc..edb4cd03db 100644
--- 
a/test/src/main/java/org/apache/accumulo/test/functional/MemoryStarvedMinCIT.java
+++ 
b/test/src/main/java/org/apache/accumulo/test/functional/MemoryStarvedMinCIT.java
@@ -56,8 +56,6 @@ public class MemoryStarvedMinCIT extends 
SharedMiniClusterBase {
       cfg.setNumTservers(1);
       cfg.setMemory(ServerType.TABLET_SERVER, 256, MemoryUnit.MEGABYTE);
       // Configure the LowMemoryDetector in the TabletServer
-      // check on 1s intervals and set low mem condition if more than 80% of
-      // the heap is used.
       cfg.setProperty(Property.GENERAL_LOW_MEM_DETECTOR_INTERVAL, "5s");
       cfg.setProperty(Property.GENERAL_LOW_MEM_DETECTOR_THRESHOLD,
           Double.toString(MemoryStarvedScanIT.FREE_MEMORY_THRESHOLD));
diff --git 
a/test/src/main/java/org/apache/accumulo/test/functional/MemoryStarvedScanIT.java
 
b/test/src/main/java/org/apache/accumulo/test/functional/MemoryStarvedScanIT.java
index d06cef1308..59b9a535b8 100644
--- 
a/test/src/main/java/org/apache/accumulo/test/functional/MemoryStarvedScanIT.java
+++ 
b/test/src/main/java/org/apache/accumulo/test/functional/MemoryStarvedScanIT.java
@@ -70,8 +70,6 @@ public class MemoryStarvedScanIT extends 
SharedMiniClusterBase {
       cfg.setNumTservers(1);
       cfg.setMemory(ServerType.TABLET_SERVER, 256, MemoryUnit.MEGABYTE);
       // Configure the LowMemoryDetector in the TabletServer
-      // check on 1s intervals and set low mem condition if more than 80% of
-      // the heap is used.
       cfg.setProperty(Property.GENERAL_LOW_MEM_DETECTOR_INTERVAL, "5s");
       cfg.setProperty(Property.GENERAL_LOW_MEM_DETECTOR_THRESHOLD,
           Double.toString(FREE_MEMORY_THRESHOLD));
@@ -87,7 +85,7 @@ public class MemoryStarvedScanIT extends 
SharedMiniClusterBase {
     }
   }
 
-  public static final double FREE_MEMORY_THRESHOLD = 0.20D;
+  public static final double FREE_MEMORY_THRESHOLD = 0.40D;
 
   private static final Logger LOG = 
LoggerFactory.getLogger(MemoryStarvedScanIT.class);
   private static final DoubleAdder SCAN_START_DELAYED = new DoubleAdder();

Reply via email to