On Tue, Nov 25, 2008 at 3:20 PM, <j16sdiz at freenetproject.org> wrote:
> Author: j16sdiz
> Date: 2008-11-25 07:20:10 +0000 (Tue, 25 Nov 2008)
> New Revision: 23847
>
> Modified:
> trunk/freenet/src/freenet/support/io/TempBucketFactory.java
> Log:
> workaround for TempBucket leak
Some TempBucket are not freed. This cause lots of unnecessary bucket migration.
This patch workaround the issue by using finalizer and WeakReference.
There are a few minor problem in this patch, but I guess this is
better then just leaking.
> Modified: trunk/freenet/src/freenet/support/io/TempBucketFactory.java
> ===================================================================
> --- trunk/freenet/src/freenet/support/io/TempBucketFactory.java 2008-11-25
> 03:06:36 UTC (rev 23846)
> +++ trunk/freenet/src/freenet/support/io/TempBucketFactory.java 2008-11-25
> 07:20:10 UTC (rev 23847)
> @@ -6,6 +6,7 @@
> import java.io.IOException;
> import java.io.InputStream;
> import java.io.OutputStream;
> +import java.lang.ref.WeakReference;
> import java.util.LinkedList;
> import java.util.Queue;
> import java.util.Random;
> @@ -345,10 +346,17 @@
> if(isRAMBucket()) {
> _hasFreed(currentSize);
> synchronized(ramBucketQueue) {
> - ramBucketQueue.remove(this);
> + ramBucketQueue.remove(this); // FIXME
> }
> }
> }
> +
> + protected void finalize() {
> + if (!hasBeenFreed) {
> + Logger.normal(this, "TempBucket not freed,
> size=" + size() + ", isRAMBucket=" + isRAMBucket());
> + free();
> + }
> + }
> }
>
> // Storage accounting disabled by default.
> @@ -443,7 +451,7 @@
> TempBucket toReturn = new TempBucket(now, realBucket);
> if(useRAMBucket) { // No need to consider them for migration
> if they can't be migrated
> synchronized(ramBucketQueue) {
> - ramBucketQueue.add(toReturn);
> + ramBucketQueue.add(new
> WeakReference<TempBucket>(toReturn));
> }
> }
> return toReturn;
> @@ -456,14 +464,25 @@
> final Queue<TempBucket> toMigrate = new
> LinkedList<TempBucket>();
> do {
> synchronized(ramBucketQueue) {
> - final TempBucket tmpBucket =
> ramBucketQueue.peek();
> - if((tmpBucket == null) ||
> (tmpBucket.creationTime + RAMBUCKET_MAX_AGE > now))
> + final WeakReference<TempBucket> tmpBucketRef
> = ramBucketQueue.peek();
> + if (tmpBucketRef == null)
> shouldContinue = false;
> else {
> - if(logMINOR)
> - Logger.minor(this, "The
> bucket is "+TimeUtil.formatTime(now - tmpBucket.creationTime)+" old: we will
> force-migrate it to disk.");
> - ramBucketQueue.remove(tmpBucket);
> - toMigrate.add(tmpBucket);
> + TempBucket tmpBucket =
> tmpBucketRef.get();
> + if (tmpBucket == null) {
> +
> ramBucketQueue.remove(tmpBucketRef);
> + continue; // ugh. this is
> freed
> + }
> +
> + if (tmpBucket.creationTime +
> RAMBUCKET_MAX_AGE > now)
> + shouldContinue = false;
> + else {
> + if (logMINOR)
> + Logger.minor(this,
> "The bucket is " + TimeUtil.formatTime(now - tmpBucket.creationTime)
> + + " old: we
> will force-migrate it to disk.");
> +
> ramBucketQueue.remove(tmpBucketRef);
> + toMigrate.add(tmpBucket);
> + }
> }
> }
> } while(shouldContinue);
> @@ -486,7 +505,7 @@
> }
> }
>
> - private final Queue<TempBucket> ramBucketQueue = new
> LinkedBlockingQueue<TempBucket>();
> + private final Queue<WeakReference<TempBucket>> ramBucketQueue = new
> LinkedBlockingQueue<WeakReference<TempBucket>>();
>
> private Bucket _makeFileBucket() {
> Bucket fileBucket = new
> TempFileBucket(filenameGenerator.makeRandomFilename(), filenameGenerator);
>
> _______________________________________________
> cvs mailing list
> cvs at freenetproject.org
> http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs
>