mirror of
				https://github.com/LamGC/ContentGrabbingJi.git
				synced 2025-11-04 10:36:57 +00:00 
			
		
		
		
	[Change] CacheStore-Local 调整 AutoCleanTimer 初始化细节, 将 AutoCleanTimer 对 Cleanable 的强引用改为弱引用;
[Change] AutoCleanTimer 简化 static 代码块内容, 移除 debug 相关代码(目前用不上); [Change] AutoCleanTimer 对 Cleanable 的强引用改为弱引用, 以防止 CacheStore 无法被回收导致内存泄漏;
This commit is contained in:
		@ -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);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user