Python実行時に処理がKilledされた場合のデバッグ方法調査の備忘録



Python実行時のKilled発生例


以下のコードであえてKilledになる状況を作ってみます。

Python:
import itertools

list_length = 1000
element_list = [0] * list_length

for i in range(list_length):
    element_list[i] = "hoge"

for element_num in range(len(element_list)):
    all_combinations = list(itertools.combinations(element_list, element_num))
上記を実行すると「Killed」となって処理が終了します。

出力:
Killed
次に何が原因でKilledとなり処理が終了したのか、以下で突き止めていきます。


Killed原因の確認


Killedの要因を知るには、以下のコマンドを実行します。

コマンド:
dmesg -T | grep -i 'killed process'
dmesg」はカーネルが出力したメッセージを表示するLinuxのコマンドです。"-T"で時刻を表示します。

出力として、次のようなものとなると思います。

出力例:
[Sat Mar 15 18:19:12 2025] Out of memory: Killed process 22010 (python3) total-vm:8612588kB, anon-rss:7464864kB, file-rss:0kB, shmem-rss:0kB, UID:1000 pgtables:16828kB oom_score_adj:0

ここではOOM(Out of Memory)エラーなので、メモリフルでメモリリークが発生したことが分かります。

前述のコードは、リスト要素の全通りの組み合わせを生成してリストへ格納していく処理を行っているため、ざっくり2^n(n=1000)個近くの要素をリストに格納しようとした過程でメモリが不足しています。

スクリプト実行中にメモリ使用量が100%になったことで、OSによって処理が強制的に終了させられました。処理実行中にタスクマネージャー(htopコマンド等)を見ると、確かにメモリ使用量がみるみる増えていることが分かります。


メモリ不足によるKilled要因解決


先ほどのitertoolsを使った処理であれば、一度に全ての組み合わせを生成せず、ループ毎に必要な組み合わせを生成して処理することで、メモリリークを防ぐことが出来ます。

Python:
import itertools

for element_num in range(len(element_list)):
    for conb in itertools.combinations(element_list, element_num):
        # ここで処理する

そのほかのメモリ使用量のDebugとメモリ解放などの方法などについては下記記事などを参考にしてみてください。

▼関連記事


タイムアウトなどもKilled要因としてあるので、その際は無限ループなどを疑うことになります。

以上

このエントリーをはてなブックマークに追加
コメントを閉じる

コメント

コメントフォーム
記事の評価
  • リセット
  • リセット