mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-07 00:16:57 +08:00
add full gc scheduler
This commit is contained in:
@@ -364,6 +364,8 @@ class ConfigModel(BaseModel):
|
|||||||
ENCODING_DETECTION_PERFORMANCE_MODE: bool = True
|
ENCODING_DETECTION_PERFORMANCE_MODE: bool = True
|
||||||
# 编码探测的最低置信度阈值
|
# 编码探测的最低置信度阈值
|
||||||
ENCODING_DETECTION_MIN_CONFIDENCE: float = 0.8
|
ENCODING_DETECTION_MIN_CONFIDENCE: float = 0.8
|
||||||
|
# 主动内存回收时间间隔(分钟),0为不启用
|
||||||
|
MEMORY_GC_INTERVAL: int = 30
|
||||||
|
|
||||||
# ==================== 安全配置 ====================
|
# ==================== 安全配置 ====================
|
||||||
# 允许的图片缓存域名
|
# 允许的图片缓存域名
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ from app.helper.wallpaper import WallpaperHelper
|
|||||||
from app.log import logger
|
from app.log import logger
|
||||||
from app.schemas import Notification, NotificationType, Workflow, ConfigChangeEventData
|
from app.schemas import Notification, NotificationType, Workflow, ConfigChangeEventData
|
||||||
from app.schemas.types import EventType, SystemConfigKey
|
from app.schemas.types import EventType, SystemConfigKey
|
||||||
|
from app.utils.gc import auto_gc
|
||||||
from app.utils.singleton import SingletonClass
|
from app.utils.singleton import SingletonClass
|
||||||
from app.utils.timer import TimerUtils
|
from app.utils.timer import TimerUtils
|
||||||
|
|
||||||
@@ -181,6 +182,11 @@ class Scheduler(metaclass=SingletonClass):
|
|||||||
"name": "订阅日历缓存",
|
"name": "订阅日历缓存",
|
||||||
"func": SubscribeChain().cache_calendar,
|
"func": SubscribeChain().cache_calendar,
|
||||||
"running": False
|
"running": False
|
||||||
|
},
|
||||||
|
"full_gc": {
|
||||||
|
"name": "主动内存回收",
|
||||||
|
"func": self.full_gc,
|
||||||
|
"running": False
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,6 +419,19 @@ class Scheduler(metaclass=SingletonClass):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 主动内存回收
|
||||||
|
if settings.MEMORY_GC_INTERVAL:
|
||||||
|
self._scheduler.add_job(
|
||||||
|
self.start,
|
||||||
|
"interval",
|
||||||
|
id="full_gc",
|
||||||
|
name="主动内存回收",
|
||||||
|
hours=settings.MEMORY_GC_INTERVAL,
|
||||||
|
kwargs={
|
||||||
|
'job_id': 'full_gc'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
# 初始化工作流服务
|
# 初始化工作流服务
|
||||||
self.init_workflow_jobs()
|
self.init_workflow_jobs()
|
||||||
|
|
||||||
@@ -747,6 +766,13 @@ class Scheduler(metaclass=SingletonClass):
|
|||||||
"""
|
"""
|
||||||
SchedulerChain().clear_cache()
|
SchedulerChain().clear_cache()
|
||||||
|
|
||||||
|
@auto_gc
|
||||||
|
def full_gc(self):
|
||||||
|
"""
|
||||||
|
主动内存回收
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
def user_auth(self):
|
def user_auth(self):
|
||||||
"""
|
"""
|
||||||
用户认证检查
|
用户认证检查
|
||||||
|
|||||||
+125
@@ -0,0 +1,125 @@
|
|||||||
|
"""
|
||||||
|
内存回收装饰器模块
|
||||||
|
提供装饰器用于在函数执行后立即回收内存
|
||||||
|
"""
|
||||||
|
import gc
|
||||||
|
import functools
|
||||||
|
import psutil
|
||||||
|
import os
|
||||||
|
from typing import Callable, Any, Optional
|
||||||
|
|
||||||
|
from app.log import logger
|
||||||
|
|
||||||
|
|
||||||
|
def memory_gc(force_collect: bool = True,
|
||||||
|
log_memory_usage: bool = False) -> Callable:
|
||||||
|
"""
|
||||||
|
内存回收装饰器
|
||||||
|
|
||||||
|
Args:
|
||||||
|
force_collect: 是否强制执行垃圾回收,默认True
|
||||||
|
log_memory_usage: 是否记录内存使用日志,默认False
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
装饰器函数
|
||||||
|
"""
|
||||||
|
def decorator(func: Callable) -> Callable:
|
||||||
|
@functools.wraps(func)
|
||||||
|
def wrapper(*args, **kwargs) -> Any:
|
||||||
|
# 记录函数执行前的内存使用情况
|
||||||
|
memory_before = None
|
||||||
|
memory_after = None
|
||||||
|
if log_memory_usage:
|
||||||
|
memory_before = get_memory_usage()
|
||||||
|
logger.info(f"函数 {func.__name__} 执行前内存使用: {memory_before}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 执行原函数
|
||||||
|
result = func(*args, **kwargs)
|
||||||
|
|
||||||
|
# 记录函数执行后的内存使用情况
|
||||||
|
if log_memory_usage:
|
||||||
|
memory_after = get_memory_usage()
|
||||||
|
logger.info(f"函数 {func.__name__} 执行后内存使用: {memory_after}")
|
||||||
|
if memory_before:
|
||||||
|
memory_diff = memory_after - memory_before
|
||||||
|
logger.info(f"函数 {func.__name__} 内存变化: {memory_diff} MB")
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
finally:
|
||||||
|
# 强制垃圾回收
|
||||||
|
if force_collect:
|
||||||
|
collected = gc.collect()
|
||||||
|
if log_memory_usage:
|
||||||
|
logger.info(f"函数 {func.__name__} 垃圾回收完成,回收对象数: {collected}")
|
||||||
|
|
||||||
|
# 记录垃圾回收后的内存使用情况
|
||||||
|
if log_memory_usage:
|
||||||
|
memory_after_gc = get_memory_usage()
|
||||||
|
logger.info(f"函数 {func.__name__} 垃圾回收后内存使用: {memory_after_gc}")
|
||||||
|
if memory_after:
|
||||||
|
memory_freed = memory_after - memory_after_gc
|
||||||
|
logger.info(f"函数 {func.__name__} 释放内存: {memory_freed} MB")
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def get_memory_usage() -> float:
|
||||||
|
"""
|
||||||
|
获取当前进程的内存使用情况(MB)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
内存使用量(MB)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
process = psutil.Process(os.getpid())
|
||||||
|
memory_info = process.memory_info()
|
||||||
|
return memory_info.rss / 1024 / 1024 # 转换为MB
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"获取内存使用情况失败: {e}")
|
||||||
|
return 0.0
|
||||||
|
|
||||||
|
|
||||||
|
def memory_monitor(threshold_mb: Optional[float] = None) -> Callable:
|
||||||
|
"""
|
||||||
|
内存监控装饰器,当内存使用超过阈值时自动触发垃圾回收
|
||||||
|
|
||||||
|
Args:
|
||||||
|
threshold_mb: 内存阈值(MB),超过此值将触发垃圾回收
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
装饰器函数
|
||||||
|
"""
|
||||||
|
def decorator(func: Callable) -> Callable:
|
||||||
|
@functools.wraps(func)
|
||||||
|
def wrapper(*args, **kwargs) -> Any:
|
||||||
|
# 检查内存使用情况
|
||||||
|
current_memory = get_memory_usage()
|
||||||
|
|
||||||
|
if threshold_mb and current_memory > threshold_mb:
|
||||||
|
logger.warning(f"内存使用超过阈值 {threshold_mb}MB,当前使用: {current_memory}MB")
|
||||||
|
collected = gc.collect()
|
||||||
|
logger.info(f"自动垃圾回收完成,回收对象数: {collected}")
|
||||||
|
|
||||||
|
# 执行原函数
|
||||||
|
result = func(*args, **kwargs)
|
||||||
|
|
||||||
|
# 执行后再次检查并回收
|
||||||
|
if threshold_mb:
|
||||||
|
memory_after = get_memory_usage()
|
||||||
|
if memory_after > threshold_mb:
|
||||||
|
collected = gc.collect()
|
||||||
|
logger.info(f"函数执行后垃圾回收完成,回收对象数: {collected}")
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
# 便捷的装饰器别名
|
||||||
|
memory_cleanup = memory_gc
|
||||||
|
auto_gc = memory_gc(force_collect=True, log_memory_usage=True)
|
||||||
|
memory_watch = memory_monitor
|
||||||
Reference in New Issue
Block a user