前提・実現したいこと
Windows10でAnacondaをインストールし,python3の環境で開発しています.
Pythonのsubprocessを使用して外部プログラムを実行して結果を処理する,ということを何度も繰り返すコードが必要になり,作成したものの,メモリを消費し続け,解放されないという現象に悩まされています.
ターミナルを終了させても,一向にメモリが解放される様子はありません.
この問題を解決し,メモリが正常に開放されながら実行されることを目指しています.
発生している問題・エラーメッセージ
問題の原因を追究した結果,添付のコードで同じ問題を起こすことができたため,Popenの部分で発生している,ということまで分かっています.
※実行する外部プログラムはlsを使用していますが,これに意味はありません.
このコードをPC再起動直後のメモリ使用率22%のときに実行すると,終了後にはメモリ使用量57%となり,ターミナルを終了させてもメモリは解放されませんでした.
(CPU Ryzen 7 3700X,メモリ16GBの環境です)
該当のソースコード
Python
1import subprocess 2 3for i in range(1,100000): 4 p = subprocess.Popen(['ls', '-l'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.STDOUT, shell=False) 5 out,err = p.communicate() 6 print('i: {} out: {}\n'.format(i,out.decode())) 7 p.terminate()
試したこと
この問題は,Spyder,JupyterNotebook,Anaconda Promptのうちどれを使用しても発生しました.※上記のメモリ増加率はAnaconda Promptのときのものです.
調べた情報の中には,shell=Trueだとプロセスを終了できなくなった,という内容[1]がありましたが,今回はshell=Falseで発生しています.
[1] How to terminate a python subprocess launched with shell=True,
https://stackoverflow.com/questions/4789837/how-to-terminate-a-python-subprocess-launched-with-shell-true, ※2020/4/14に閲覧
補足情報(FW/ツールのバージョンなど)
Pythonのバージョンは 3.7.4,condaのバージョンは 4.7.12 です.
2020/4/15 追記
Ubuntu 18.04にAnacondaをインストールし,再起動後このプログラムを動かした場合,このメモリが開放されない問題は発生しませんでした.なので,Windows10でのみ起きるものと推測されます.(CPU A10-7800 メモリ12GB,python 3.7.6,conda 4.8.2)
2020/4/15 追記
Windows10でこのプログラムを2回実行した際のリソースモニターを含めたスクリーンショット(※画面左のショートカット部分はカットしています)はこちらです.
※実行しているmemory_explosion.pyの中身が上記コードです.
リソースモニターでコミット順に並べた際にはバックグラウンドで動いているskype,steamなどが上位に来ますが,何か莫大にメモリを消費しているプロセスは見当たりません.このときは1回目終了時57%→2回目終了時88%となっています.ls.exeは実行中は下の方に現れますが,終了後は無くなります.しかし,メモリは消費されたままです.
2020/4/15 追記
上で示したスクリーンショットでは,ワーキングセットを見ていなかったため,再度2回実行した際に,ワーキングセットでソートしたものを示します.
2020/4/15 追記
ノートPCのWindows10でこのプログラムを実行したところ,メモリの開放に不具合は起きませんでした.
実行環境:CPU i7-8550U,メモリ 16GB, Python 3.7.6,conda 4.8.2
Windows10で,というよりはハードウェア構成から起因している問題の可能性も出てきました.
2020/4/16 追記
AnacondaとPythonのバージョン違いが原因かもしれないので,メインPCの環境を更新して実行しました.
実行中,じわじわとメモリ使用率が増えていき,1回実行前後では物理メモリ使用率は35%→65%となり,終了後も変化しないため,バージョンが古いという点は問題ではありませんでした.
実行環境:CPU Ryzen 7 3700X,メモリ16GB,Python 3.7.7,conda 4.8.3
2020/4/16 追記
RAMMapを使用して,開始前(メモリ使用率33%),1回目終了時(メモリ使用率65%),2回目終了時(メモリ使用率94%)の各時点で更新し,内容を見ました.
Page Tableが実行するごとに約2.7GB増加しているほか,Unusedなのにアクティブなメモリというものが増加しています.Diver Lockedにはほぼ変化はありませんでした.
2020/4/16 追記
リソースモニターでは,終了後ls.exeは消えていきましたが,RAMMapを終了後に起動してProcesesを見ると,ls.exeは大量に残っていました.これらのls.exeがPage Table分のメモリを保持したままになっているようです.
また,セーフモードで起動してプログラムを実行した場合,メモリ解放の問題は発生せず使用率は10%台のままでした.
回答2件
あなたの回答
tips
プレビュー