python多進程中的內(nèi)存復(fù)制(實例講解)
比較好奇python對于多進程中copy on write機制的實際使用情況。目前從實驗結(jié)果來看,python 使用multiprocessing來創(chuàng)建多進程時,無論數(shù)據(jù)是否不會被更改,子進程都會復(fù)制父進程的狀態(tài)(內(nèi)存空間數(shù)據(jù)等)。所以如果主進程耗的資源較多時,不小心就會造成不必要的大量的內(nèi)存復(fù)制,從而可能導(dǎo)致內(nèi)存爆滿的情況。
示例
舉個例子,假設(shè)主進程讀取了一個大文件對象的所有行,然后通過multiprocessing創(chuàng)建工作進程,并循環(huán)地將每一行數(shù)據(jù)交給工作進程來處理:
def parse_lines(args): #working ... def main_logic(): f = open(filename , 'r') lines = f.readlines() f.close() pool = multiprocessing.Pool(processes==4) rel = pool.map(parse_lines , itertools.izip(lines , itertools.repeat(second_args)) , int(len(lines)/4)) pool.close() pool.join()
以下是top及ps結(jié)果:
(四個子進程)
(父進程及四個子進程)
由上兩張圖可以看出父進程及子進程都各自占用了1.4G左右的內(nèi)存空間。而大部分內(nèi)存空間存儲的是讀數(shù)據(jù)lines,所以這樣的內(nèi)存開銷太浪費。
優(yōu)化計劃
1: 在主進程初期未導(dǎo)入大量的py庫之前創(chuàng)建進程,或者動態(tài)加載py庫。
2:通過內(nèi)存共享來減少內(nèi)存的開銷。
3: 主進程不再讀取文件對象,交給每個工作進程去讀取文件中的相應(yīng)部分。
改進代碼:
def line_count(file_name): count = -1 #讓空文件的行號顯示0 for count,line in enumerate(open(file_name)): pass #enumerate格式化成了元組,count就是行號,因為從0開始要+1 return count+1 def parse_lines(args): f = open(args[0] , 'r') lines = f.readlines()[args[1]:args[2]] #read some lines f.close() #working def main_logic(filename,process_num): line_count = line_count(filename) avg_len = int(line_count/process_num) left_cnt = line_count%process_num; pool = multiprocessing.Pool(processes=process_num) for i in xrange(0,process_num): ext_cnt = (i>=process_num-1 and [left_cnt] or [0])[0] st_line = i*avg_len pool.apply_async(parse_lines, ((filename, st_line, st_line+avg_len+ext_cnt),)) #指定進程讀某幾行數(shù)據(jù) pool.close() pool.join()
再次用top或者ps來查看進程的內(nèi)存使用情況:
(四個子進程)
(父進程及四個子進程)
小結(jié)
對比兩次的內(nèi)存使用情況,改進代碼后父進程及子進程所占用的內(nèi)存明顯減少;所有內(nèi)存占用相當(dāng)于原來的一半,這就是減少內(nèi)存復(fù)制的效果。
關(guān)于內(nèi)存使用這方面還有不少優(yōu)化方法和空間,稍后繼續(xù)研究。
以上這篇python多進程中的內(nèi)存復(fù)制(實例講解)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
python實現(xiàn)將文件夾內(nèi)的每張圖片批量分割成多張
這篇文章主要為大家詳細(xì)介紹了python實現(xiàn)將文件夾內(nèi)的每張圖片批量分割成多張,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-07-07如何在scrapy中集成selenium爬取網(wǎng)頁的方法
這篇文章主要介紹了如何在scrapy中集成selenium爬取網(wǎng)頁的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Python進行數(shù)據(jù)可視化Plotly與Dash的應(yīng)用小結(jié)
數(shù)據(jù)可視化是數(shù)據(jù)分析中至關(guān)重要的一環(huán),它能夠幫助我們更直觀地理解數(shù)據(jù)并發(fā)現(xiàn)隱藏的模式和趨勢,本文主要介紹了Python進行數(shù)據(jù)可視化Plotly與Dash的應(yīng)用小結(jié),具有一定的參考價值,感興趣的可以了解一下2024-04-04