diff options
| author | reger <reger18@arcor.de> | 2015-02-11 01:42:01 +0100 |
|---|---|---|
| committer | reger <reger18@arcor.de> | 2015-02-11 01:42:01 +0100 |
| commit | df83fcc4fc5026ce75edd680642f3d46ab5d3507 (patch) | |
| tree | 50caa95efcd5b65a68d65cc5da2ffdb5fbb9ec2b | |
| parent | 8ff76f8682c1b8a6e86438d788e7ce468a723834 (diff) | |
disable optimistic GC assumption in StandardMemoryStrategy
After several tests found that eom is not prevented. Major reason in testing was assumption future GC will free avg of last 5 GC.
Disabeling this check improved eom exceptions.
Added simplest testcase used for verification
| -rw-r--r-- | source/net/yacy/kelondro/util/StandardMemoryStrategy.java | 12 | ||||
| -rw-r--r-- | test/net/yacy/kelondro/util/MemoryControlTest.java | 43 |
2 files changed, 49 insertions, 6 deletions
diff --git a/source/net/yacy/kelondro/util/StandardMemoryStrategy.java b/source/net/yacy/kelondro/util/StandardMemoryStrategy.java index 58d3582d3..35e82732a 100644 --- a/source/net/yacy/kelondro/util/StandardMemoryStrategy.java +++ b/source/net/yacy/kelondro/util/StandardMemoryStrategy.java @@ -36,7 +36,7 @@ public class StandardMemoryStrategy extends MemoryStrategy { private final long[] gcs = new long[5]; private int gcs_pos = 0; - private long properMbyte = 0L; + private long properByte = 0L; // treshold private long prevTreshold = 0L; private int tresholdCount = 0; private boolean proper = true; @@ -157,7 +157,7 @@ public class StandardMemoryStrategy extends MemoryStrategy { } private boolean request0(final long size, final boolean force) { final long avg = getAverageGCFree(); - if (avg >= size) return true; + // if (avg >= size) return true; // optimistic view, GC may just has happened long avail = available(); if (avail >= size) return true; if (log.isFine()) { @@ -177,7 +177,7 @@ public class StandardMemoryStrategy extends MemoryStrategy { + (size >> 10) + " / " + (avail >> 10) + " / " + (avg >> 10) + " KB)"); } checkProper(avail); - return avail >= size; + return this.proper && avail >= size; } if (log.isFine()) log.fine("former GCs indicate to not be able to free enough memory (requested/available/average: " + (size >> 10) + " / " + (avail >> 10) + " / " + (avg >> 10) + " KB)"); @@ -209,13 +209,13 @@ public class StandardMemoryStrategy extends MemoryStrategy { */ @Override protected void setProperMbyte(final long mbyte) { - this.properMbyte = mbyte; + this.properByte = mbyte << 20; // convert to byte this.tresholdCount = 0; } private void checkProper(final long available) { // disable proper state if memory is less than treshold - 4 times, maximum 11 minutes between each detection - if ((available >> 20) < this.properMbyte) { + if ((available) < this.properByte) { final long t = System.currentTimeMillis(); if(this.prevTreshold + 11L /* minutes */ * 60000L > t) { this.tresholdCount++; @@ -227,7 +227,7 @@ public class StandardMemoryStrategy extends MemoryStrategy { log.info("checkProper: below treshold; tresholdCount: " + this.tresholdCount + "; proper: " + this.proper); } - else if (!this.proper && (available >> 20) > (this.properMbyte * 2L)) // we were wrong! + else if (!this.proper && (available) > (this.properByte * 2L)) // we were wrong! resetProperState(); } diff --git a/test/net/yacy/kelondro/util/MemoryControlTest.java b/test/net/yacy/kelondro/util/MemoryControlTest.java new file mode 100644 index 000000000..5c8666436 --- /dev/null +++ b/test/net/yacy/kelondro/util/MemoryControlTest.java @@ -0,0 +1,43 @@ +
+package net.yacy.kelondro.util;
+
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+
+public class MemoryControlTest {
+
+ final int onemb = 1024 * 1024;
+
+ /**
+ * Test of request method, of class MemoryControl.
+ */
+ @Test
+ public void testRequest_StandardStrategy() {
+ MemoryControl.setStandardStrategy(true);
+ MemoryControl.setProperMbyte(24);
+
+ int memblock = onemb * 13; // memsize to allocate
+
+ int iterations = (int) MemoryControl.available() / memblock;
+ int arraysize = (int) MemoryControl.maxMemory() / memblock + 10;
+
+ byte[][] x = new byte[arraysize][];
+
+ int i = 0;
+
+ while (i < arraysize && MemoryControl.request(memblock, false)) {
+ x[i] = new byte[memblock];
+ // for realistic test produce some memory avail to GC
+ if (MemoryControl.request(memblock, false)) {
+ x[i] = new byte[memblock];
+ }
+
+ i++;
+ }
+ System.out.println("allocated " + i + " * " + memblock/onemb + " MB = " + i*memblock/onemb + " MB");
+
+ assertTrue(i >= iterations);
+ }
+
+}
|
