From df83fcc4fc5026ce75edd680642f3d46ab5d3507 Mon Sep 17 00:00:00 2001 From: reger Date: Wed, 11 Feb 2015 01:42:01 +0100 Subject: [PATCH] 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 --- .../kelondro/util/StandardMemoryStrategy.java | 12 +++--- .../yacy/kelondro/util/MemoryControlTest.java | 43 +++++++++++++++++++ 2 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 test/net/yacy/kelondro/util/MemoryControlTest.java 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); + } + +}