您好,登錄后才能下訂單哦!
這篇文章主要介紹了Python垃圾回收及Linux Fork實例分析的相關(guān)知識,內(nèi)容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Python垃圾回收及Linux Fork實例分析文章都會有所收獲,下面我們一起來看看吧。
前言:
在口袋助理看到了其他部門的同事針對Python2
內(nèi)存占用做的一點優(yōu)化工作,自己比較感興趣,遂記錄下。
fork是Linux提供的創(chuàng)建子進程的系統(tǒng)調(diào)用。為了優(yōu)化創(chuàng)建進程速度,Linux內(nèi)核使用了Copy-on-Write
的方式去創(chuàng)建進程,所謂Copy-on-Write
是指執(zhí)行fork之后,
內(nèi)核并不立即給子進程分配物理內(nèi)存空間,而是讓子進程的虛內(nèi)存映射到父進程的物理內(nèi)存。僅僅當子進程向地址空間中執(zhí)行寫入操作時,才給它分配一段物理內(nèi)存。
通過這種方式既優(yōu)化了進程創(chuàng)建的時間,又減少了子進程的內(nèi)存占用。
Python GC采用引用技術(shù)的方式去管理對每個對象的引用,每一個被GC跟蹤的對象會由一個PyGC_Head的結(jié)構(gòu)體去表示。如下所示,其中gc_refs
就是每個對象的引用計數(shù)值,
當我們在子進程中讀取父進程創(chuàng)建的對象的時候,就會導(dǎo)致子進程的虛地址空間中的gc_refs
加1,從而觸發(fā)了內(nèi)核的缺頁中斷,這是內(nèi)核就會給子進程創(chuàng)建新的物理內(nèi)存。
僅僅是簡單的讀取操作就會導(dǎo)致新的內(nèi)存空間產(chǎn)生。
/* GC information is stored BEFORE the object structure. */ typedef union _gc_head { struct { union _gc_head *gc_next; union _gc_head *gc_prev; Py_ssize_t gc_refs; } gc; long double dummy; /* force worst-case alignment */ } PyGC_Head;
python3的解決方法:
針對這個問題,Python3.7增加了三組API(有instagram團體提交的)[1]。
freeze
用于將GC追蹤的所有對象都移動到永生代(permanent generation)
,之后垃圾回收會忽略這些被設(shè)置為永生代的對象。
實際使用中,我們可以在父進程中執(zhí)行freeze
函數(shù),然后子進程中使用和父進程共享的對象,這樣對象的引用技術(shù)就不會增加,從而避免了COW的發(fā)生。
python2的解決方法:
(1) 針對Python2,我們可以簡單的把Python3的相關(guān)函數(shù)移植過來
(2) 使用multiprocessing.Array去共享數(shù)據(jù)。Array會從共享內(nèi)存中取一段取存儲數(shù)據(jù),并不會增加引用技術(shù)值,從而觸發(fā)COW。
實現(xiàn)方面,Array使用Posix共享內(nèi)存 + mmap去實現(xiàn)。[3]
#!/usr/bin/env python # coding=utf-8 from multiprocessing import Array import os import sys def foo(): shared_cache = Array('i', range(0, 100), lock=False) pid = os.fork() if pid > 0: print("parent:", sys.getrefcount(shared_cache)) elif pid == 0: print("child:", sys.getrefcount(shared_cache)) foo()
關(guān)于“Python垃圾回收及Linux Fork實例分析”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“Python垃圾回收及Linux Fork實例分析”知識都有一定的了解,大家如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。