mirror of
https://github.com/LamGC/ContentGrabbingJi.git
synced 2025-04-29 22:27:33 +00:00
[Change] CacheStore-Local 调整 AutoCleanTimer 初始化细节, 将 AutoCleanTimer 对 Cleanable 的强引用改为弱引用;
[Change] AutoCleanTimer 简化 static 代码块内容, 移除 debug 相关代码(目前用不上); [Change] AutoCleanTimer 对 Cleanable 的强引用改为弱引用, 以防止 CacheStore 无法被回收导致内存泄漏;
This commit is contained in:
parent
11327a368f
commit
e2c6aca34c
@ -5,12 +5,14 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定时清理机制.
|
* 定时清理机制.
|
||||||
@ -20,7 +22,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
*/
|
*/
|
||||||
public class AutoCleanTimer implements Runnable {
|
public class AutoCleanTimer implements Runnable {
|
||||||
|
|
||||||
private final static Set<Cleanable> CLEANABLE_STORE_SET = new CopyOnWriteArraySet<>();
|
private final static Set<WeakReference<Cleanable>> CLEANABLE_STORE_SET = new CopyOnWriteArraySet<>();
|
||||||
|
|
||||||
private final static ScheduledExecutorService SCHEDULED_EXECUTOR =
|
private final static ScheduledExecutorService SCHEDULED_EXECUTOR =
|
||||||
new ScheduledThreadPoolExecutor(1,
|
new ScheduledThreadPoolExecutor(1,
|
||||||
@ -32,22 +34,9 @@ public class AutoCleanTimer implements Runnable {
|
|||||||
|
|
||||||
private final static Logger log = LoggerFactory.getLogger(AutoCleanTimer.class);
|
private final static Logger log = LoggerFactory.getLogger(AutoCleanTimer.class);
|
||||||
|
|
||||||
private final static AtomicBoolean DEBUG_ENABLE = new AtomicBoolean(false);
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
SCHEDULED_EXECUTOR.scheduleAtFixedRate(new AutoCleanTimer(), 100L, 100L, TimeUnit.MILLISECONDS);
|
SCHEDULED_EXECUTOR.scheduleAtFixedRate(new AutoCleanTimer(), 100L, 100L, TimeUnit.MILLISECONDS);
|
||||||
Thread shutdownHook = new Thread(SCHEDULED_EXECUTOR::shutdown);
|
Runtime.getRuntime().addShutdownHook(new Thread(SCHEDULED_EXECUTOR::shutdownNow, "ShutdownThread-AutoClean"));
|
||||||
shutdownHook.setName("ShutdownThread-AutoClean");
|
|
||||||
Runtime.getRuntime().addShutdownHook(shutdownHook);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否启用调试模式.
|
|
||||||
* <p>启用后将会打印相关日志.
|
|
||||||
* @param enable 是否启用调试模式.
|
|
||||||
*/
|
|
||||||
public static void setDebugEnable(boolean enable) {
|
|
||||||
DEBUG_ENABLE.set(enable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,15 +44,7 @@ public class AutoCleanTimer implements Runnable {
|
|||||||
* @param store 已实现Cleanable的对象
|
* @param store 已实现Cleanable的对象
|
||||||
*/
|
*/
|
||||||
public static void add(Cleanable store) {
|
public static void add(Cleanable store) {
|
||||||
CLEANABLE_STORE_SET.add(store);
|
CLEANABLE_STORE_SET.add(new WeakReference<>(store));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 移除已添加的缓存库
|
|
||||||
* @param store 需要从AutoCleanTimer移除的对象
|
|
||||||
*/
|
|
||||||
public static void remove(Cleanable store) {
|
|
||||||
CLEANABLE_STORE_SET.remove(store);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AutoCleanTimer() {}
|
private AutoCleanTimer() {}
|
||||||
@ -74,12 +55,23 @@ public class AutoCleanTimer implements Runnable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLEANABLE_STORE_SET.forEach(cleanable -> {
|
Iterator<WeakReference<Cleanable>> iterator = CLEANABLE_STORE_SET.iterator();
|
||||||
try {
|
Set<WeakReference<Cleanable>> toBeCleanReference = new HashSet<>();
|
||||||
cleanable.clean();
|
while(iterator.hasNext()) {
|
||||||
} catch (Exception e) {
|
WeakReference<Cleanable> reference = iterator.next();
|
||||||
log.error("{} 执行清理动作时发生异常:\n{}", cleanable.toString(), Throwables.getStackTraceAsString(e));
|
Cleanable store = reference.get();
|
||||||
|
if (store == null) {
|
||||||
|
// 由于 COW ArraySet 的 Iterator 不支持 remove 操作,
|
||||||
|
// 所以先收集起来, 等完成所有清理工作后统一删除引用.
|
||||||
|
toBeCleanReference.add(reference);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
try {
|
||||||
|
store.clean();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("{} 执行清理动作时发生异常:\n{}", store.toString(), Throwables.getStackTraceAsString(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CLEANABLE_STORE_SET.removeAll(toBeCleanReference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user