如何监控Jupyter Notebook的RAM分配与使用量?AWS环境异常排查
AWS EC2实例中Jupyter Notebook内存监控异常及正确方法
在AWS云服务器虚拟机环境中,需监控Jupyter Notebook的RAM使用,避免代码占用内存超过阈值时自动终止,但尝试两种监测方法后输出与实际内存情况不符:
方法1(psutil):
代码:import psutil # This is not correct! print('RAM Used [GB]:', psutil.virtual_memory()[3]/1000000000) print('RAM Total [GB]:', psutil.virtual_memory()[0]/1000000000)异常表现:输出总RAM约33GB、已用约8.3GB,实际实例总RAM为16GB、已用约2.8GB。
方法2(os模块调用free命令):
代码:import os # Getting all memory using os.popen() total_memory, used_memory, free_memory = map( int, os.popen('free -t -m').readlines()[-1].split()[1:]) # Memory usage print("RAM memory % used:", round((used_memory/total_memory) * 100, 2)) print(f"total_memory = {total_memory}, used_memory = {used_memory}, free_memory = {free_memory}")异常表现:输出总RAM约31470MB(约32GB)、已用约7960MB,实际应为总16GB、已用约2.8GB。
额外现象:将实例调整为8GB RAM时,两种方法的结果接近实际;调回16GB后异常复现。
问题原因
- 方法2核心问题:
free -t会统计物理内存(RAM)+交换分区(Swap)的总和,AWS部分实例类型默认开启与物理内存容量相当的Swap分区,因此16GB实例的总统计值接近32GB,8GB实例则接近16GB,你误将这个总和当成了物理内存。 - 方法1问题:
psutil.virtual_memory()[3]返回的used值包含系统缓存、缓冲区等非应用程序占用的内存,并非Jupyter代码实际占用的内存;部分AWS实例的虚拟化层或内存配置(如hugepages)也可能导致总内存统计偏差。
正确监测方法
一、准确统计实例物理内存(系统级)
方法A:修正os模块调用free命令
去掉-t参数,直接读取物理内存(Mem行)数据,同时排除缓存/缓冲区计算应用实际占用内存:
import os def get_system_ram(): # 读取free命令输出,提取Mem行数据 mem_info = os.popen('free -m').readlines()[1].split() total_ram = int(mem_info[1]) used_ram = int(mem_info[2]) # 计算应用实际占用内存(减去缓存、缓冲区) actual_used = int(mem_info[2]) - int(mem_info[5]) - int(mem_info[6]) free_ram = int(mem_info[3]) return { "total_ram_gb": total_ram / 1024, "system_used_gb": used_ram / 1024, "app_used_gb": actual_used / 1024, "free_ram_gb": free_ram / 1024 } ram_stats = get_system_ram() print(f"物理总内存: {ram_stats['total_ram_gb']:.2f} GB") print(f"系统统计已用内存: {ram_stats['system_used_gb']:.2f} GB") print(f"应用实际占用内存: {ram_stats['app_used_gb']:.2f} GB") print(f"空闲内存: {ram_stats['free_ram_gb']:.2f} GB")
方法B:修正psutil内存统计
用virtual_memory()的total作为物理总内存,active作为应用实际占用内存(排除缓存):
import psutil mem = psutil.virtual_memory() total_ram_gb = mem.total / (1024**3) system_used_gb = mem.used / (1024**3) app_used_gb = mem.active / (1024**3) free_ram_gb = mem.free / (1024**3) print(f"物理总内存: {total_ram_gb:.2f} GB") print(f"系统统计已用内存: {system_used_gb:.2f} GB") print(f"应用实际占用内存: {app_used_gb:.2f} GB") print(f"空闲内存: {free_ram_gb:.2f} GB")
二、监控Jupyter进程内存(精准到当前代码)
如果需求是监控Jupyter中运行的代码本身占用的内存,直接监测当前Python进程:
import psutil import os def get_jupyter_process_memory(): process = psutil.Process(os.getpid()) # 物理内存占用(RSS) rss_gb = process.memory_info().rss / (1024**3) # 虚拟内存占用 vms_gb = process.memory_info().vms / (1024**3) return {"rss_gb": rss_gb, "vms_gb": vms_gb} proc_mem = get_jupyter_process_memory() print(f"当前Jupyter进程物理内存占用: {proc_mem['rss_gb']:.2f} GB") print(f"当前Jupyter进程虚拟内存占用: {proc_mem['vms_gb']:.2f} GB")
三、内存超限自动终止实现
结合进程监控,设置阈值后自动终止进程:
import psutil import os import sys import time MEMORY_LIMIT_GB = 50 # 自定义内存阈值 def check_memory_limit(): proc = psutil.Process(os.getpid()) mem_used = proc.memory_info().rss / (1024**3) if mem_used >= MEMORY_LIMIT_GB: print(f"内存占用超过阈值 {MEMORY_LIMIT_GB} GB,自动终止进程") sys.exit(1) # 示例:每分钟检查一次 while True: check_memory_limit() time.sleep(60)
内容的提问来源于stack exchange,提问作者Kas Knicely
相关产品推荐
相关产品推荐

