メモリの使用量が綺麗に右肩上がりになっているアプリがあったので、メモリリークの発生箇所を特定する方法を調べてみたところ、標準モジュールの tracemalloc
で出来そうなので、使ってみました。
tracemalloc
については以下のページを参考にさせていただきました。
環境
- Python 3.8.10
サンプルコード
スレッド化し、5秒ごとにメモリ使用量トップ10と、メモリ増加量トップ10を表示するようにしてみました。
import tracemalloc
import time
from datetime import datetime
from threading import Thread
class MemoryCheker:
def __init__(self):
self.__is_running = False
self.__snapshot = None
def start(self):
print(f'{self.__class__.__name__} start')
self.__is_running = True
self.__thread = Thread(target=self.__run)
self.__thread.start()
def stop(self):
print(f'{self.__class__.__name__} stopping')
self.__is_running = False
self.__thread.join()
print(f'{self.__class__.__name__} stopped')
def __run(self):
while self.__is_running:
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
print(f'[ Top 10 : {datetime.now()}]')
for stat in top_stats[:10]:
print(stat)
if self.__snapshot != None:
top_stats = snapshot.compare_to(self.__snapshot, 'lineno')
print('[ Top 10 Difference ]')
for stat in top_stats[:10]:
print(stat)
self.__snapshot = snapshot
time.sleep(5)
if __name__ == '__main__':
tracemalloc.start()
memory_checker = MemoryChecker()
memory_checker.start()
# do something
memory_checker.stop()
これでメモリリークしている箇所にあたりをつけ、原因を特定することができました。