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;
> + }
> + });
> + }
> }
So when we reach the memory limit, we turn off caching and get more churn and
therefore hit it more quickly ... well I suppose it's a tradeoff.
>
> 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();
> + }
> +
I've changed this to do a GC and then re-check. If we are still at the limit
for total memory and have less than 8MB free, *then* we hit the low memory
handler.
I'm not entirely convinced though. We will end up doing a lot more full GCs
this way ... often on systems that don't have a memory problem.
> 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();
> - }
> - }
> - }
> }
Why did you delete the pubkey cache clearing OOM hook?
>
> 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;
> }
-------------- 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/bd149707/attachment.pgp>