I'm not convinced about this. Reaching 8MB less than the max memory is normal - for example if you use the -server VM, it will always happen, and soon after startup, because the VM doesn't GC until it reaches the limit.
IMHO we should only execute the low memory hooks if we either get an OOM, or if we have less than 8MB left *after a garbage collection*. Note that there are command line options to make explicit garbage collection a no-op, so the latter isn't easy; and explicitly GCing on a regular schedule is generally regarded as a *bad* thing. On Friday 02 May 2008 11:10, j16sdiz at freenetproject.org wrote: > Author: j16sdiz > Date: 2008-05-02 10:10:12 +0000 (Fri, 02 May 2008) > New Revision: 19675 > > Modified: > trunk/freenet/src/freenet/crypt/SHA256.java > trunk/freenet/src/freenet/node/MemoryChecker.java > trunk/freenet/src/freenet/node/Node.java > trunk/freenet/src/freenet/store/BerkeleyDBFreenetStore.java > trunk/freenet/src/freenet/support/OOMHandler.java > trunk/freenet/src/freenet/support/OOMHook.java > Log: > alternative low memory / out of memory handling > > > Modified: trunk/freenet/src/freenet/crypt/SHA256.java > =================================================================== > --- trunk/freenet/src/freenet/crypt/SHA256.java 2008-05-02 10:09:13 UTC > (rev 19674) > +++ trunk/freenet/src/freenet/crypt/SHA256.java 2008-05-02 10:10:12 UTC > (rev 19675) > @@ -44,6 +44,8 @@ > import freenet.node.Node; > import freenet.node.NodeInitException; > import freenet.support.Logger; > +import freenet.support.OOMHandler; > +import freenet.support.OOMHook; > import freenet.support.io.Closer; > > /** > @@ -105,7 +107,7 @@ > String algo = md256.getAlgorithm(); > if(!(algo.equals("SHA-256") || algo.equals("SHA256"))) > throw new IllegalArgumentException("Should be SHA-256 > but is " + algo); > - if (digests.size() > 16) // don't cache too many of them > + if (digests.size() > 16 || noCache) // don't cache too many of > them > return; > md256.reset(); > digests.add(md256); > @@ -121,4 +123,20 @@ > public static int getDigestLength() { > return HASH_SIZE; > } > + > + private static boolean noCache = false; > + > + static { > + OOMHandler.addOOMHook(new OOMHook() { > + public void handleLowMemory() throws Exception { > + digests.clear(); > + noCache = true; > + } > + > + public void handleOutOfMemory() throws Exception { > + digests.clear(); > + noCache = true; > + } > + }); > + } > } > > Modified: trunk/freenet/src/freenet/node/MemoryChecker.java > =================================================================== > --- trunk/freenet/src/freenet/node/MemoryChecker.java 2008-05-02 10:09:13 UTC (rev 19674) > +++ trunk/freenet/src/freenet/node/MemoryChecker.java 2008-05-02 10:10:12 UTC (rev 19675) > @@ -4,6 +4,7 @@ > package freenet.node; > > import freenet.support.Logger; > +import freenet.support.OOMHandler; > import freenet.support.SizeUtil; > > public class MemoryChecker implements Runnable { > @@ -42,6 +43,11 @@ > > Logger.normal(this, "Memory in use: "+SizeUtil.formatSize((r.totalMemory()-r.freeMemory()))); > > + if (r.freeMemory() < 4096 * 1024 * 1024) { // free memory < 8 MB > + Logger.error(this, "memory too low, trying to free > some"); > + OOMHandler.lowMemory(); > + } > + > int sleeptime = aggressiveGCModificator; > if(sleeptime <= 0) { // We are done > ps.queueTimedJob(this, 120 * 250); // 30 sec > > Modified: trunk/freenet/src/freenet/node/Node.java > =================================================================== > --- trunk/freenet/src/freenet/node/Node.java 2008-05-02 10:09:13 UTC (rev 19674) > +++ trunk/freenet/src/freenet/node/Node.java 2008-05-02 10:10:12 UTC (rev 19675) > @@ -124,7 +124,7 @@ > /** > * @author amphibian > */ > -public class Node implements TimeSkewDetectorCallback, GetPubkey, OOMHook { > +public class Node implements TimeSkewDetectorCallback, GetPubkey { > > private static boolean logMINOR; > > @@ -1604,8 +1604,6 @@ > e.printStackTrace(); > throw new NodeInitException(NodeInitException.EXIT_COULD_NOT_START_UPDATER, "Could not create Updater: "+e); > } > - > - OOMHandler.addOOMHook(this); > > Logger.normal(this, "Node constructor completed"); > System.out.println("Node constructor completed"); > @@ -3306,23 +3304,4 @@ > public void setDispatcherHook(NodeDispatcherCallback cb) { > this.dispatcher.setHook(cb); > } > - > - /** > - * Free some memory > - */ > - public void handleOOM() throws Exception { > - if (cachedPubKeys != null) { > - Object value; > - do { > - value = cachedPubKeys.popKey(); > - } while (value != null); > - } > - if (recentlyCompletedIDs != null) { > - synchronized (recentlyCompletedIDs) { > - // half it size > - while (recentlyCompletedIDs.size() > > MAX_RECENTLY_COMPLETED_IDS / 2) > - recentlyCompletedIDs.pop(); > - } > - } > - } > } > > Modified: trunk/freenet/src/freenet/store/BerkeleyDBFreenetStore.java > =================================================================== > --- trunk/freenet/src/freenet/store/BerkeleyDBFreenetStore.java > 2008-05-02 10:09:13 UTC (rev 19674) > +++ trunk/freenet/src/freenet/store/BerkeleyDBFreenetStore.java > 2008-05-02 10:10:12 UTC (rev 19675) > @@ -2239,15 +2239,30 @@ > bf.get(data); > } > > - public void handleOOM() throws Exception { > - if (storeRAF != null) > - storeRAF.getFD().sync(); > - if (keysRAF != null) > - keysRAF.getFD().sync(); > - if (lruRAF != null) > - lruRAF.getFD().sync(); > + public void handleLowMemory() throws Exception { > + // Flush all > + if (storeFC != null) > + storeFC.force(true); > + if (keysFC != null) > + keysFC.force(true); > + if (lruFC != null) > + lruFC.force(true); > } > > + public void handleOutOfMemory() throws Exception { > + // database likely to be corrupted, > + // reconstruct it just in case > + reconstructFile.createNewFile(); > + > + // Flush all > + if (storeFC != null) > + storeFC.force(true); > + if (keysFC != null) > + keysFC.force(true); > + if (lruFC != null) > + lruFC.force(true); > + } > + > /** > * @return > */ > > Modified: trunk/freenet/src/freenet/support/OOMHandler.java > =================================================================== > --- trunk/freenet/src/freenet/support/OOMHandler.java 2008-05-02 10:09:13 UTC (rev 19674) > +++ trunk/freenet/src/freenet/support/OOMHandler.java 2008-05-02 10:10:12 UTC (rev 19675) > @@ -33,6 +33,30 @@ > } > } > > + /** > + * Call this when running low of memory > + */ > + public static void lowMemory() { > + System.gc(); > + System.runFinalization(); > + > + // iterate all oom hooks > + Iterator it = oomHooks.iterator(); > + while (it.hasNext()) { > + OOMHook hook = ((OOMHook) it.next()); > + if (hook != null) { > + try { > + hook.handleLowMemory(); > + } catch (Throwable t) { > + //ignore > + } > + } > + } > + > + System.gc(); > + System.runFinalization(); > + } > + > public static void handleOOM(OutOfMemoryError e) { > if (isOOM) { > Logger.error(null, "Double OOM", e); > @@ -51,20 +75,18 @@ > > System.gc(); > System.runFinalization(); > - > + > // iterate all oom hooks > Iterator it = oomHooks.iterator(); > while (it.hasNext()) { > OOMHook hook = ((OOMHook) it.next()); > if (hook != null) { > try { > - hook.handleOOM(); > + hook.handleOutOfMemory(); > } catch (Throwable t) { > //ignore > } > } > - > - System.gc(); > } > > System.gc(); > > Modified: trunk/freenet/src/freenet/support/OOMHook.java > =================================================================== > --- trunk/freenet/src/freenet/support/OOMHook.java 2008-05-02 10:09:13 UTC (rev 19674) > +++ trunk/freenet/src/freenet/support/OOMHook.java 2008-05-02 10:10:12 UTC (rev 19675) > @@ -5,9 +5,14 @@ > */ > public interface OOMHook { > /** > - * Handle OutOfMemoryError > + * Handle running low of memory > * > * (try to free some cache, save the files, etc). > */ > - void handleOOM() throws Exception; > + void handleLowMemory() throws Exception; > + > + /** > + * Handle running out of memory > + */ > + void handleOutOfMemory() throws Exception; > } > > _______________________________________________ > cvs mailing list > cvs at freenetproject.org > http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs > > -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available URL: <https://emu.freenetproject.org/pipermail/devl/attachments/20080503/08e0a449/attachment.pgp>