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
pull/1/head
reger 10 years ago
parent 8ff76f8682
commit df83fcc4fc

@ -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();
}

@ -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);
}
}
Loading…
Cancel
Save