以下の様に描画用のプロセスを別途作成・終了させればメモリリークを防げます。
from multiprocessing import Pool
import matplotlib.pyplot as plt
import numpy as np
# プロット用のメソッド
# plt.clf() や plt.close() をしなくてもプロセス終了時に自動でメモリが解放される。
def plot(args):
x, y = args
plt.plot(x, y)
# プロットする値
x = np.arange(1e7)
y = np.arange(1e7)
# プロット用のプロセスを作成し、その中で描画処理を行う
p = Pool(1)
p.map(plot, [[x,y]])
p.close()
実際にメモリが解放されているかは以下のコードで確認できます。
from multiprocessing import Pool
import matplotlib.pyplot as plt
import numpy as np
# プロット用のメソッド
# plt.clf()・plt.close() をしなくてもプロセス終了時に自動でメモリが解放される。
def plot(args):
x, y = args
plt.plot(x, y)
# 検証用に以下をしても良い
plt.tight_layout()
plt.savefig('aa.jpeg')
# 10回プロットしてメモリ使用量が変わらないかを調べる
for i in range(10):
# プロットする値
x = np.arange(1e7)
y = np.arange(1e7)
# プロット用のプロセスを作成し、その中で描画処理を行う
p = Pool(1)
p.map(plot, [[x,y]])
p.close()
# メモリ使用量を表示
import psutil
mem = psutil.virtual_memory().free / 1e9
print(i, f'memory used: {mem} [GB]')
ちなみに、例えば以下の様な場合にメモリリークが起こります。(参考:plt.close() だけではメモリが解放されない場合がある - Qiita)
-
plt.close()
しかしていない場合 -
plt.clf()
→plt.close()
をしているが、plt.tight_layout()
やplt.savefig()
をしている場合