mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-05-06 20:42:43 +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_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.schemas import Notification, NotificationType, Workflow, ConfigChangeEventData
|
||||
from app.schemas.types import EventType, SystemConfigKey
|
||||
from app.utils.gc import auto_gc
|
||||
from app.utils.singleton import SingletonClass
|
||||
from app.utils.timer import TimerUtils
|
||||
|
||||
@@ -181,6 +182,11 @@ class Scheduler(metaclass=SingletonClass):
|
||||
"name": "订阅日历缓存",
|
||||
"func": SubscribeChain().cache_calendar,
|
||||
"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()
|
||||
|
||||
@@ -747,6 +766,13 @@ class Scheduler(metaclass=SingletonClass):
|
||||
"""
|
||||
SchedulerChain().clear_cache()
|
||||
|
||||
@auto_gc
|
||||
def full_gc(self):
|
||||
"""
|
||||
主动内存回收
|
||||
"""
|
||||
pass
|
||||
|
||||
def user_auth(self):
|
||||
"""
|
||||
用户认证检查
|
||||
|
||||
125
app/utils/gc.py
Normal file
125
app/utils/gc.py
Normal file
@@ -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