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
相关产品推荐
相关产品推荐

