Register shutdown hooks for caches, in the first step of cleaning up

resources on shutdown, which is important in Android as the JVM
isn't going away. More to do.
This commit is contained in:
zzz
2011-06-14 19:08:15 +00:00
parent 620ec536c2
commit d50cf13085
6 changed files with 78 additions and 2 deletions

View File

@ -83,6 +83,18 @@ public class SDSCache<V extends SimpleDataStructure> {
_log.debug("New SDSCache for " + rvClass + " data size: " + len +
" max: " + size + " max mem: " + (len * size));
I2PAppContext.getGlobalContext().statManager().createRateStat(_statName, "Hit rate", "Router", new long[] { 10*60*1000 });
I2PAppContext.getGlobalContext().addShutdownTask(new Shutdown());
}
/**
* @since 0.8.8
*/
private class Shutdown implements Runnable {
public void run() {
synchronized(_cache) {
_cache.clear();
}
}
}
/**

View File

@ -107,8 +107,18 @@ public class DecayingBloomFilter {
context.statManager().createRateStat("router.decayingBloomFilter." + name + ".log10(falsePos)",
"log10 of the false positive rate (must have net.i2p.util.DecayingBloomFilter=DEBUG)",
"Router", new long[] { Math.max(60*1000, durationMs) });
context.addShutdownTask(new Shutdown());
}
/**
* @since 0.8.8
*/
private class Shutdown implements Runnable {
public void run() {
clear();
}
}
public long getCurrentDuplicateCount() { return _currentDuplicates; }
public int getInsertedCount() {

View File

@ -93,8 +93,18 @@ public class DecayingHashSet extends DecayingBloomFilter {
"Size", "Router", new long[] { Math.max(60*1000, durationMs) });
context.statManager().createRateStat("router.decayingHashSet." + name + ".dups",
"1000000 * Duplicates/Size", "Router", new long[] { Math.max(60*1000, durationMs) });
context.addShutdownTask(new Shutdown());
}
/**
* @since 0.8.8
*/
private class Shutdown implements Runnable {
public void run() {
clear();
}
}
/** unsynchronized but only used for logging elsewhere */
@Override
public int getInsertedCount() {

View File

@ -2,6 +2,7 @@ package net.i2p.util;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ThreadFactory;
@ -48,12 +49,25 @@ public class SimpleScheduler {
_threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024))));
_executor = new ScheduledThreadPoolExecutor(_threads, new CustomThreadFactory());
_executor.prestartAllCoreThreads();
// don't bother saving ref to remove hook if somebody else calls stop
_context.addShutdownTask(new Shutdown());
}
/**
* Removes the SimpleScheduler.
* @since 0.8.8
*/
private class Shutdown implements Runnable {
public void run() {
stop();
}
}
/**
* Stops the SimpleScheduler.
* Subsequent executions should not throw a RejectedExecutionException.
*/
public void stop() {
_executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
_executor.shutdownNow();
}

View File

@ -53,16 +53,32 @@ public class SimpleTimer {
executor.setDaemon(true);
executor.start();
}
_context.addShutdownTask(new Shutdown());
}
/**
* @since 0.8.8
*/
private class Shutdown implements Runnable {
public void run() {
removeSimpleTimer();
}
}
/**
* Removes the SimpleTimer.
*/
public void removeSimpleTimer() {
synchronized(_events) {
runn.setAnswer(false);
_events.clear();
_eventTimes.clear();
_events.notifyAll();
}
synchronized (_readyEvents) {
_readyEvents.clear();
_readyEvents.notifyAll();
}
}
/**

View File

@ -3,6 +3,7 @@ package net.i2p.util;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ThreadFactory;
@ -48,12 +49,25 @@ public class SimpleTimer2 {
_threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024))));
_executor = new CustomScheduledThreadPoolExecutor(_threads, new CustomThreadFactory());
_executor.prestartAllCoreThreads();
// don't bother saving ref to remove hook if somebody else calls stop
_context.addShutdownTask(new Shutdown());
}
/**
* Removes the SimpleTimer.
* @since 0.8.8
*/
private class Shutdown implements Runnable {
public void run() {
stop();
}
}
/**
* Stops the SimpleTimer.
* Subsequent executions should not throw a RejectedExecutionException.
*/
public void stop() {
_executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
_executor.shutdownNow();
}