在使用 Python 進行影像處理 或 資料科學運算 時,我們常常需要載入大量圖片或產生大量矩陣。
如果沒有妥善管理記憶體,程式很容易因為 RAM 爆滿 (Out Of Memory, OOM) 而崩潰。
尤其是在舊電腦win7 32位元狀況下,容易發生這個問題。MemoryError: Unable to allocate 12.9 MiB for an array with shape (1628, 2775, 3)
and data type uint8
本文將用範例與實驗結果,完整說明:
- 為什麼
del
與gc.collect()
是必要的 - 什麼情況下記憶體會暴增
- 正確釋放記憶體的方法與效益
測試結果圖
沒有釋放記憶體,就會一直疊加。

釋放記憶體,保持穩定,完全不會隨著迴圈增加。

為什麼需要記憶體管理
Python 內建的垃圾回收(Garbage Collection, GC)會自動釋放不再被引用的變數,但在影像處理這種情境下,GC 不一定能及時處理記憶體釋放,原因包括:
- 變數還有引用
影像處理過程中,如果把處理結果存進一個列表或變數,Python 不會釋放這塊記憶體。 - NumPy 與底層 C 記憶體池
NumPy 陣列的底層記憶體由 C 管理,GC 只會釋放 Python 物件,不會立即歸還底層記憶體給作業系統。 - 記憶體碎片化
記憶體釋放不及時,或者釋放後無法馬上回收,導致表面上看起來記憶體佔用不斷增加。
程式範例
import numpy as np
import gc
import psutil
import os
import time
def print_memory_usage(note=""):
process = psutil.Process(os.getpid())
print(f"[Memory {note}] {process.memory_info().rss / 1024 / 1024:.2f} MB")
def simulate_processing(num_images=30, image_size=(4000, 4000, 3), release_memory=False):
"""
num_images: 模擬影像數量
image_size: 每張影像大小
release_memory: 是否釋放記憶體
"""
print(f"\n{'='*20} {'WITH' if release_memory else 'WITHOUT'} MEMORY RELEASE {'='*20}\n")
processed_images = [] # 模擬把每張處理後的結果保留下來
for i in range(num_images):
print_memory_usage(f"Before creating image {i+1}")
# 模擬創造一張高解析度影像 (RGB)
img = np.random.randint(0, 256, size=image_size, dtype=np.uint8)
# 模擬簡單處理:轉灰階
gray = np.mean(img, axis=2).astype(np.uint8)
# 把結果暫存 (模擬程式需要暫時保存結果)
processed_images.append(gray)
print_memory_usage(f"After processing image {i+1}")
if release_memory:
# 釋放當前影像記憶體
del img
del gray
processed_images.clear() # 清空暫存
gc.collect()
print_memory_usage(f"After GC image {i+1}")
else:
print_memory_usage(f"Image {i+1} kept in memory")
time.sleep(0.3)
# 測試沒釋放記憶體
simulate_processing(num_images=10, release_memory=False)
# 測試有釋放記憶體
simulate_processing(num_images=10, release_memory=True)
什麼時候需要 gc.collect()
- 需要釋放大物件或大量 NumPy 陣列時
如影像批次處理、影片逐幀分析、深度學習資料預處理。 - 長時間執行的程式
例如服務型程式、持續運行的監控系統。 - 迴圈產生大量資料
當記憶體曲線持續上升,就代表該手動釋放。
最佳實踐建議
- 盡量不要保留不必要的變數
處理完一張影像立即釋放,不要一次堆積。 - 批次處理
大量影像可分批處理,每批處理完成釋放記憶體。 - 監控記憶體
用psutil
實時檢查記憶體狀況。 - 避免不必要的拷貝
使用 NumPy 的原地操作可以減少額外記憶體消耗。