티스토리 뷰

728x90
반응형

안녕하세요.

 

이번 포스팅은 Python의 threading과 psutil을 사용해서 함수실행중의 메모리 사용량을 측정하는 방법에 대해서 다룹니다.

 

1. psutil

psutil은 Python의 패키지중 하나로, Python System and ProcessUtilities의 약자입니다.

 

해당 패키지를 이용하면 컴퓨터의 CPU, 메모리, 디스크, 네트워크 사용량 등을 체크할 수가 있습니다.

 

이번 포스팅에서는 psutil의 Process를 사용합니다.

 

Process를 사용해서 현재 Process가 사용중인 메모리를 측정합니다.

import psutil
def memory_usage():
    p = psutil.Process()
    rss = p.memory_info().rss/2**20
    print(f'mem usage : {rss}MB')
memory_usage():
#>> mem usage : 156.152MB

문제는 메모리를 측정하는 작업은 Blocking 작업이기 때문에

 

Serial한 코드에서는 중간중간 메모리 사용량을 기록할 수가 없습니다.

import pandas as pd
import numpy as np
import psutil
import matplotlib.pyplot as plt
def memory_usage():
    p = psutil.Process()
    rss = p.memory_info().rss/2**20
    print(f'mem usage : {rss:10.5f}MB')


cnt = 50000000
memory_usage()
dt = np.random.random(cnt)
memory_usage()
temp = pd.Series(dt, index = np.random.random(cnt))
memory_usage()
temp = temp.sort_values()
memory_usage()
#>> 실제 패키지 내부에서 일어나는 동작 중간중간
#>> Memory사용량을 trace 할 수가 없음

이때 thread를 활용하게 됩니다.

2. threading

Thread의 경우 코드의 동시성을 확보해서, Blocking인 코드를 Non-Blocking으로 만들 수가 있습니다.

 

이때 Thread를 사용해서 buffer를 관리하고

 

이 buffer에다가 Thread를 사용해서 메모리값을 기록할 수 있습니다.

mem_buff = []
def record_mem():    
    global mem_list
    while True:
        p = psutil.Process()        
        buff.append(p.memory_info().rss/2**20)
        
import threading
t = threading.Thread(target = record_mem)
t.start()
...

t.join()

위 방법과, thread끼리 메모리를 공유하는점을 활용하면 아래와같이 활용이 가능해집니다.

import numpy as np
import psutil
import matplotlib.pyplot as plt
mem_buff = []
mem_flag = [True]
def record_mem():    
    global mem_list
    while mem_flag[0]:
        p = psutil.Process()        
        mem_buff.append(p.memory_info().rss/2**20)


import threading
t = threading.Thread(target = record_mem)
t.start()
#메모리를 Tracing할 코드================
dt = np.random.random(cnt)
temp = pd.Series(dt, index = np.random.random(cnt))
temp = temp.sort_values()
#메모리를 Tracing할 코드================
#코드 실행 완료 후 flag를 변경하여 무한루프 종료
mem_flag[0] = False
t.join()

plt.title("Memory Tracing")
plt.ylabel("Memory_usage")
plt.xlabel("Time")
plt.plot(mem_buff)

이대 해당 X축이 Time으로 되어있지만

 

Thread의 실행에 따라 X축이 정확히 시간이 아닐 수 있습니다.

 

이때 dict를 활용하여 조금더 개선하면, 시간에 따라 보다 정확한 memory 사용량을 알 수 있습니다.

 

import pandas as pd
import numpy as np
import psutil
import matplotlib.pyplot as plt
import time
st = time.time()
mem_buff = {}
mem_flag = [True]
def record_mem():    
    global mem_buff, st
    while mem_flag[0]:
        p = psutil.Process()
        rss = p.memory_info().rss/2**20        
        mem_buff[time.time()-st] = (rss)


import threading
t = threading.Thread(target = record_mem)
t.start()
dt = np.random.random(cnt)
temp = pd.Series(dt, index = np.random.random(cnt))
temp.sort_values(inplace = True)
mem_flag[0] = False
t.join()

plt.title("Memory Tracing")
plt.ylabel("Memory_usage")
plt.xlabel("Time")
plt.plot(mem_buff.keys(), [mem_buff[i] for i in mem_buff.keys()])
plt.show()

728x90
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함