You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python脚本(PyAutoGUI+OpenCV)内存占用过高问题求助

内存泄漏优化方案与自动重启方法

核心问题分析

你的脚本内存暴涨的主要原因是无限递归调用:find_and_click_text 和 skip 互相调用,且未找到目标时递归自身,导致调用栈持续累积,内存无法释放。此外,每次函数执行都重复读取模板图片,也会增加不必要的内存开销。

优化方案(彻底解决内存泄漏)

1. 替换递归为循环

递归不适合这种持续运行的场景,改用 while 循环可避免调用栈无限增长,从根源解决内存堆积问题。

2. 预加载模板图片

将模板图片在脚本启动时加载一次,而非每次函数调用都从磁盘读取,减少IO开销和内存碎片。

3. 修复按键释放问题

原代码中使用 keyDown 但未调用 keyUp,会导致按键一直处于按下状态,需补充释放操作。

4. 显式触发垃圾回收

在循环中定期触发垃圾回收,帮助清理不再使用的对象。

优化后的代码

import pyautogui
import cv2
import numpy as np
import time
import gc

# 预加载模板图片,仅初始化一次
TEMPLATE_TEXT = cv2.imread("C:/Users/Owner/template2.png", cv2.IMREAD_COLOR)
TEMPLATE_SKIP = cv2.imread("C:/Users/Owner/skip2.png", cv2.IMREAD_COLOR)
H_TEXT, W_TEXT = TEMPLATE_TEXT.shape[:-1]
H_SKIP, W_SKIP = TEMPLATE_SKIP.shape[:-1]

def take_screenshot():
    screenshot = pyautogui.screenshot()
    screenshot = np.array(screenshot)
    return cv2.cvtColor(screenshot, cv2.COLOR_RGB2BGR)

def find_and_click_text():
    num = 0
    while True:
        screenshot = take_screenshot()
        result = cv2.matchTemplate(screenshot, TEMPLATE_TEXT, cv2.TM_CCOEFF_NORMED)
        _, max_val, _, max_loc = cv2.minMaxLoc(result)
        
        if max_val > 0.8:
            # 定位并点击目标
            center_x = max_loc[0] + W_TEXT / 2
            center_y = max_loc[1] + H_TEXT / 2
            pyautogui.moveTo((center_x, center_y))
            pyautogui.click()
            # 释放之前按下的按键
            pyautogui.keyUp('fn')
            pyautogui.keyUp('f12')
            # 切换到跳过逻辑
            skip()
            break
        else:
            num += 1
            if num >= 10:
                skip()
                break
            time.sleep(0.1)  # 减少CPU占用
        gc.collect()  # 触发垃圾回收

def skip():
    num = 0
    while True:
        screenshot = take_screenshot()
        result = cv2.matchTemplate(screenshot, TEMPLATE_SKIP, cv2.TM_CCOEFF_NORMED)
        _, max_val2, _, max_loc2 = cv2.minMaxLoc(result)
        
        if max_val2 > 0.8:
            center_x = max_loc2[0] + W_SKIP / 2
            center_y = max_loc2[1] + H_SKIP / 2
            pyautogui.moveTo((center_x, center_y))
            pyautogui.click()
            pyautogui.keyUp('fn')
            pyautogui.keyUp('f8')
            time.sleep(0.5)
            find_and_click_text()
            break
        else:
            num += 1
            if num >= 10:
                find_and_click_text()
                break
            time.sleep(0.1)
        gc.collect()

if __name__ == "__main__":
    find_and_click_text()

自动重启方案(作为 fallback)

若优化后仍存在内存问题,可使用以下两种方式实现自动重启:

方法1:基于内存阈值重启

使用 psutil 库监控内存占用,超过设定阈值时自动重启脚本:

import os
import psutil
import subprocess
import time

# 配置参数
MAIN_SCRIPT = "your_main_script.py"  # 替换为你的主脚本文件名
MEMORY_THRESHOLD_GB = 2  # 内存超过2GB时重启

def restart_script():
    # 终止现有进程
    for proc in psutil.process_iter(['pid', 'cmdline']):
        try:
            if MAIN_SCRIPT in ' '.join(proc.info['cmdline']):
                proc.kill()
        except (psutil.NoSuchProcess, psutil.AccessDenied):
            pass
    # 启动新进程
    subprocess.Popen(["python", MAIN_SCRIPT])

if __name__ == "__main__":
    restart_script()  # 首次启动主脚本
    while True:
        for proc in psutil.process_iter(['pid', 'cmdline']):
            try:
                if MAIN_SCRIPT in ' '.join(proc.info['cmdline']):
                    mem_usage = proc.memory_info().rss / (1024**3)  # 转换为GB
                    if mem_usage > MEMORY_THRESHOLD_GB:
                        restart_script()
                        break
            except (psutil.NoSuchProcess, psutil.AccessDenied):
                pass
        time.sleep(10)  # 每10秒检查一次

安装依赖:pip install psutil

方法2:定时重启

固定时间间隔重启脚本,适用于内存增长规律的场景:

import subprocess
import time

MAIN_SCRIPT = "your_main_script.py"
RESTART_INTERVAL = 300  # 5分钟重启一次(单位:秒)

while True:
    proc = subprocess.Popen(["python", MAIN_SCRIPT])
    time.sleep(RESTART_INTERVAL)
    proc.kill()

内容的提问来源于stack exchange,提问作者penguinpowerss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 02:26:08