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

Win10下Python3.7使用win32gui截图内存泄漏问题求助

解决Win10下Python截图长期运行的内存泄漏问题

你已经做了不少资源释放的工作,但还是遇到了内存泄漏——这种GDI资源泄漏在手动调用win32api时确实很容易踩坑。我来帮你分析下可能的问题,再给几个靠谱的解决方案:

先看现有代码的潜在隐患

虽然你写了资源释放代码,但如果window_capture执行中抛出异常(比如文件写入失败),后续的释放逻辑就会跳过,日积月累就会导致资源泄漏。把释放代码放到try...finally块里,能确保无论是否出错都能释放资源:

import win32gui, win32ui, win32con, win32api

screen_w = 2880
screen_h = 1800
x0 = int(screen_w * 0.866)
y0 = int(screen_h * 0.14)
ww = 220
hh = 70

def window_capture(filename):
    hwnd = 0
    hwndDC = win32gui.GetWindowDC(hwnd)
    mfcDC = win32ui.CreateDCFromHandle(hwndDC)
    saveDC = mfcDC.CreateCompatibleDC()
    saveBitMap = win32ui.CreateBitmap()
    try:
        saveBitMap.CreateCompatibleBitmap(mfcDC, ww, hh)
        saveDC.SelectObject(saveBitMap)
        saveDC.BitBlt((0, 0), (ww, hh), mfcDC, (x0, y0), win32con.SRCCOPY)
        saveBitMap.SaveBitmapFile(saveDC, filename)
    finally:
        # 强制释放所有GDI资源,避免异常导致泄漏
        win32gui.DeleteObject(saveBitMap.GetHandle())
        saveDC.DeleteDC()
        mfcDC.DeleteDC()
        win32gui.ReleaseDC(hwnd, hwndDC)

count = 0
while True:
    window_capture('temp.png')
    count += 1
    if count % 1000 == 0:
        print(count)

不过即使这样,手动管理win32的GDI资源还是容易有细微泄漏(比如底层未完全回收的句柄),长期运行的话,更推荐用专门的截图库。

更适合长期运行的方案:使用mss库

mss是专门为高效、低内存的屏幕捕获设计的库,内部已经处理了所有资源管理细节,完全不用你手动释放任何资源,而且速度更快。

步骤1:安装mss

pip install mss

步骤2:替换你的代码

import mss

screen_w = 2880
screen_h = 1800
x0 = int(screen_w * 0.866)
y0 = int(screen_h * 0.14)
ww = 220
hh = 70

# 定义要截图的区域:top(上边界), left(左边界), width(宽度), height(高度)
monitor = {"top": y0, "left": x0, "width": ww, "height": hh}

count = 0
# 只初始化一次mss实例,减少重复开销
with mss.mss() as sct:
    while True:
        # 捕获指定区域的屏幕
        screenshot = sct.grab(monitor)
        # 保存为PNG文件
        mss.tools.to_png(screenshot.rgb, screenshot.size, output="temp.png")
        count += 1
        if count % 1000 == 0:
            print(count)

为什么这个方案更好?

  • 内存稳定:长期运行不会出现内存增长,因为mss会自动回收所有资源
  • 速度更快:比win32api的手动实现效率高很多
  • DPI适配:自动兼容Win10的高分屏缩放(你的2880x1800屏幕应该是200%缩放,mss会自动处理坐标,不用你手动调整)
  • 代码简洁:不用再写一堆资源释放的冗余代码

总结

如果只是临时修复现有代码,用try...finally包裹释放逻辑能缓解泄漏;但如果需要长期稳定运行,mss是更可靠的选择——它专门解决这类屏幕捕获的资源管理问题,能让你彻底摆脱内存泄漏的困扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 10:28:13