77import asyncio
88import os
99import sys
10+ import resource
11+ import psutil
12+ import time
1013from loguru import logger
1114
1215from .bot import RuleBot
1316from .config import Config
1417from .data_manager import DataManager
1518
1619
20+ def set_memory_limit ():
21+ """设置内存限制为256MB(软限制,超出时给出警告)"""
22+ try :
23+ # 256MB = 256 * 1024 * 1024 bytes
24+ memory_limit = 256 * 1024 * 1024
25+ # 设置软限制为256MB,硬限制为512MB(给一些缓冲空间)
26+ resource .setrlimit (resource .RLIMIT_AS , (memory_limit , memory_limit * 2 ))
27+ logger .info (f"已设置内存软限制为 256MB,硬限制为 512MB" )
28+
29+ # 记录当前内存使用情况
30+ try :
31+ process = psutil .Process ()
32+ current_memory = process .memory_info ().rss
33+ logger .info (f"当前内存使用: { current_memory / 1024 / 1024 :.1f} MB" )
34+ except Exception as e :
35+ logger .warning (f"获取当前内存使用失败: { e } " )
36+
37+ except Exception as e :
38+ logger .warning (f"设置内存限制失败: { e } " )
39+ # 内存限制设置失败不影响程序运行
40+
41+ def log_memory_usage ():
42+ """记录内存使用情况,接近限制时给出警告"""
43+ # 初始化静态变量(只初始化一次)
44+ if not hasattr (log_memory_usage , '_initialized' ):
45+ log_memory_usage .last_warning_time = 0
46+ log_memory_usage .last_warning_level = 0
47+ log_memory_usage .last_normal_log = 0
48+ log_memory_usage ._initialized = True
49+
50+ try :
51+ process = psutil .Process ()
52+ memory_info = process .memory_info ()
53+ memory_mb = memory_info .rss / 1024 / 1024
54+
55+ # 边界检查,确保内存值合理
56+ if memory_mb < 0 or memory_mb > 1000 : # 如果内存值异常,记录但不处理
57+ logger .warning (f"内存值异常: { memory_mb :.1f} MB,跳过处理" )
58+ return
59+
60+ current_time = time .time ()
61+ warning_cooldown = 300 # 5分钟内不重复相同级别的警告
62+
63+ # 检查是否接近硬限制
64+ if memory_mb > 480 : # 接近512MB硬限制时紧急警告
65+ if current_time - log_memory_usage .last_warning_time > warning_cooldown or log_memory_usage .last_warning_level != 3 :
66+ logger .error (f"🚨 内存使用危急: { memory_mb :.1f} MB (接近512MB硬限制,可能被系统终止)" )
67+ # 尝试主动释放一些内存
68+ import gc
69+ gc .collect ()
70+ logger .warning ("已尝试垃圾回收释放内存" )
71+ log_memory_usage .last_warning_time = current_time
72+ log_memory_usage .last_warning_level = 3
73+ elif memory_mb > 240 : # 接近256MB软限制时警告
74+ if current_time - log_memory_usage .last_warning_time > warning_cooldown or log_memory_usage .last_warning_level != 2 :
75+ logger .warning (f"⚠️ 内存使用过高: { memory_mb :.1f} MB (接近256MB软限制)" )
76+ log_memory_usage .last_warning_time = current_time
77+ log_memory_usage .last_warning_level = 2
78+ elif memory_mb > 200 : # 超过200MB时提醒
79+ if current_time - log_memory_usage .last_warning_time > warning_cooldown or log_memory_usage .last_warning_level != 1 :
80+ logger .warning (f"⚠️ 内存使用较高: { memory_mb :.1f} MB" )
81+ log_memory_usage .last_warning_time = current_time
82+ log_memory_usage .last_warning_level = 1
83+ else :
84+ # 正常时只记录一次,避免刷屏
85+ if current_time - log_memory_usage .last_normal_log > 3600 : # 1小时记录一次正常状态
86+ logger .info (f"内存使用正常: { memory_mb :.1f} MB" )
87+ log_memory_usage .last_normal_log = current_time
88+ log_memory_usage .last_warning_level = 0
89+
90+ except Exception as e :
91+ logger .warning (f"获取内存使用情况失败: { e } " )
92+
1793def main ():
1894 """主程序入口"""
1995 try :
96+ # 设置内存限制
97+ set_memory_limit ()
98+
2099 # 初始化配置
21100 config = Config ()
22101
@@ -39,11 +118,30 @@ async def init_data():
39118
40119 data_manager = asyncio .run (init_data ())
41120
121+ # 记录数据加载后的内存使用
122+ log_memory_usage ()
123+
42124 # 初始化机器人
43125 bot = RuleBot (config , data_manager )
44126
45127 # 启动机器人
46128 logger .info ("启动Telegram机器人..." )
129+
130+ # 启动定期内存检查(每10分钟检查一次)
131+ import threading
132+
133+ def memory_monitor ():
134+ while True :
135+ try :
136+ time .sleep (600 ) # 10分钟
137+ log_memory_usage ()
138+ except Exception as e :
139+ logger .warning (f"内存监控出错: { e } " )
140+ time .sleep (60 ) # 出错后等待1分钟再继续
141+
142+ monitor_thread = threading .Thread (target = memory_monitor , daemon = True )
143+ monitor_thread .start ()
144+
47145 bot .start ()
48146
49147 except KeyboardInterrupt :
0 commit comments