精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

全面解讀Python垃圾回收機制

開發 后端
由于引用計數法存在重大缺陷,循環引用時有內存泄露風險,因此 Python 還采用 標記清除法 來回收存在循環引用的垃圾對象。此外,為了提高垃圾回收( GC )效率,Python 還引入了 分代回收機制 。

[[402065]]

本文轉載自微信公眾號「小菜學編程」,作者fasionchan。轉載本文請聯系小菜學編程公眾號。

Python 內部采用 引用計數法 ,為每個對象維護引用次數,并據此回收不再需要的垃圾對象。由于引用計數法存在重大缺陷,循環引用時有內存泄露風險,因此 Python 還采用 標記清除法 來回收存在循環引用的垃圾對象。此外,為了提高垃圾回收( GC )效率,Python 還引入了 分代回收機制 。

對象跟蹤

將程序內部對象跟蹤起來,是實現垃圾回收的第一步。那么,是不是程序創建的所有對象都需要跟蹤呢?

一個對象是否需要跟蹤,取決于它會不會形成循環引用。按照引用特征,Python 對象可以分為兩類:

  • 內向型對象 ,例如 int 、float 、 str 等,這類對象不會引用其他對象,因此無法形成循環引用,無須跟蹤;
  • 外向型對象 ,例如 tuple 、 list 、 dict 等容器對象,以及函數、類實例等復雜對象,這類對象一般都會引用其他對象,存在形成循環引用的風險,因此是垃圾回收算法關注的重點;

這是一個典型的例子,橘紅色外向型對象存在循環引用的可能性,需要跟蹤;而綠色內向型對象在引用關系圖中只能作為葉子節點存在,無法形成任何環狀,因此無需跟蹤:

Python 為外向型對象分配內存時,調用位于 Modules/gcmodule.c 源文件的 _PyObject_GC_Alloc 函數。該函數在對象頭部之前預留了一些內存空間,以便垃圾回收模塊用 鏈表 將它們跟蹤起來。預留的內存空間是一個 _gc_head 結構體,它定義于 Include/objimpl.h 頭文件:

  1. typedef union _gc_head { 
  2.     struct { 
  3.         union _gc_head *gc_next; 
  4.         union _gc_head *gc_prev; 
  5.         Py_ssize_t gc_refs; 
  6.     } gc; 
  7.     long double dummy;  /* force worst-case alignment */ 
  8.     // malloc returns memory block aligned for any built-in types and 
  9.     // long double is the largest standard C type. 
  10.     // On amd64 linux, long double requires 16 byte alignment. 
  11.     // See bpo-27987 for more discussion. 
  12. } PyGC_Head; 
  • gc_next ,鏈表后向指針,指向后一個被跟蹤的對象;
  • gc_prev ,鏈表前向指針,指向前一個被跟蹤的對象;
  • gc_refs ,對象引用計數副本,在標記清除算法中使用;
  • dummy ,內存對齊用,以 64 位系統為例,確保 _gc_head 結構體大小是 16 字節的整數倍,結構體地址以 16 字節為單位對齊;

以 list 對象為例,_PyObject_GC_Alloc 函數在 PyListObject 結構體基礎上加上 _gc_head 結構體來申請內存,但只返回 PyListObject 的地址作為對象地址,而不是整塊內存的首地址:

就這樣,借助 gc_next 和 gc_prev 指針,Python 將需要跟蹤的對象一個接一個組織成 雙向鏈表 :

這個鏈表也被稱為 可收集 ( collectable )對象鏈表,Python 將從這個鏈表中收集并回收垃圾對象。

分代回收機制

Python 程序啟動后,內部可能會創建大量對象。如果每次執行標記清除法時,都需要遍歷所有對象,多半會影響程序性能。為此,Python 引入分代回收機制——將對象分為若干“代”( generation ),每次只處理某個代中的對象,因此 GC 卡頓時間更短。

那么,按什么標準劃分對象呢?是否隨機將一個對象劃分到某個代即可呢?答案是否定的。實際上,對象分代里頭也是有不少學問的,好的劃分標準可顯著提升垃圾回收的效率。

考察對象的生命周期,可以發現一個顯著特征:一個對象存活的時間越長,它下一刻被釋放的概率就越低。我們應該也有這樣的親身體會:經常在程序中創建一些臨時對象,用完即刻釋放;而定義為全局變量的對象則極少釋放。

因此,根據對象存活時間,對它們進行劃分就是一個不錯的選擇。對象存活時間越長,它們被釋放的概率越低,可以適當降低回收頻率;相反,對象存活時間越短,它們被釋放的概率越高,可以適當提高回收頻率。

對象存活時間 釋放概率 回收頻率

Python 內部根據對象存活時間,將對象分為 3 代(見 Include/internal/mem.h ):

  1. #define NUM_GENERATIONS 3 

每個代都由一個 gc_generation 結構體來維護,它同樣定義于 Include/internal/mem.h 頭文件:

  1. struct gc_generation { 
  2.     PyGC_Head head; 
  3.     int threshold; /* collection threshold */ 
  4.     int count; /* count of allocations or collections of younger 
  5.                   generations */ 
  6. }; 
  • head ,可收集對象鏈表頭部,代中的對象通過該鏈表維護;
  • threshold ,僅當 count 超過本閥值時,Python 垃圾回收操作才會掃描本代對象;
  • count ,計數器,不同代統計項目不一樣;

Python 虛擬機運行時狀態由 Include/internal/pystate.h 中的 pyruntimestate 結構體表示,它內部有一個 _gc_runtime_state ( Include/internal/mem.h )結構體,保存 GC 狀態信息,包括 3 個對象代。這 3 個代,在 GC 模塊( Modules/gcmodule.c ) _PyGC_Initialize 函數中初始化:

  1. struct gc_generation generations[NUM_GENERATIONS] = { 
  2.     /* PyGC_Head,                                 threshold,      count */ 
  3.     {{{_GEN_HEAD(0), _GEN_HEAD(0), 0}},           700,            0}, 
  4.     {{{_GEN_HEAD(1), _GEN_HEAD(1), 0}},           10,             0}, 
  5.     {{{_GEN_HEAD(2), _GEN_HEAD(2), 0}},           10,             0}, 
  6. }; 

為方便討論,我們將這 3 個代分別稱為:初生代、中生代 以及 老生代。當這 3 個代初始化完畢后,對應的 gc_generation 數組大概是這樣的:

每個 gc_generation 結構體鏈表頭節點都指向自己,換句話說每個可收集對象鏈表一開始都是空的;計數器字段 count 都被初始化為 0 ;而閥值字段 threshold 則有各自的策略。這些策略如何理解呢?

Python 調用 _PyObject_GC_Alloc 為需要跟蹤的對象分配內存時,該函數將初生代 count 計數器加一,隨后對象將接入初生代對象鏈表;當 Python 調用 PyObject_GC_Del 釋放垃圾對象內存時,該函數將初生代 count 計數器減一;_PyObject_GC_Alloc 自增 count 后如果超過閥值( 700 ),將調用 collect_generations 執行一次垃圾回收( GC )。

collect_generations 函數從老生代開始,逐個遍歷每個生代,找出需要執行回收操作( count>threshold )的最老生代。隨后調用 collect_with_callback 函數開始回收該生代,而該函數最終調用 collect 函數。

collect 函數處理某個生代時,先將比它年輕的生代計數器 count 重置為 0 ;然后將它們的對象鏈表移除,與自己的拼接在一起后執行 GC 算法(本文后半部分介紹);最后,將下一個生代計數器加一。

  • 系統每新增 701 個需要 GC 的對象,Python 就執行一次 GC 操作;
  • 每次 GC 操作需要處理的生代可能是不同的,由 count 和 threshold 共同決定;
  • 某個生代需要執行 GC ( count>hreshold ),在它前面的所有年輕生代也同時執行 GC ;
  • 對多個代執行 GC ,Python 將它們的對象鏈表拼接在一起,一次性處理;
  • GC 執行完畢后,count 清零,而后一個生代 count 加一;

下面是一個簡單的例子:初生代觸發 GC 操作,Python 執行 collect_generations 函數。它找出了達到閥值的最老生代是中生代,因此調用 collection_with_callback(1) ,1 是中生代在數組中的下標。

collection_with_callback(1) 最終執調用 collect(1) ,它先將后一個生代計數器加一;然后將本生代以及前面所有年輕生代計數器重置為零;最后調用 gc_list_merge 將這幾個可回收對象鏈表合并在一起:

最后,collect 函數執行標記清除算法,對合并后的鏈表進行垃圾回收,具體細節在本文后半部分展開介紹。

這就是分代回收機制的全部秘密,它看似復雜,但只需略加總結就可以得到幾條直白的策略:

  • 每新增 701 個需要 GC 的對象,觸發一次新生代 GC ;
  • 每執行 11 次新生代 GC ,觸發一次中生代 GC ;
  • 每執行 11 次中生代 GC ,觸發一次老生代 GC (老生代 GC 還受其他策略影響,頻率更低);
  • 執行某個生代 GC 前,年輕生代對象鏈表也移入該代,一起 GC ;
  • 一個對象創建后,隨著時間推移將被逐步移入老生代,回收頻率逐漸降低;

由于篇幅關系,分代回收部分代碼無法逐行解釋,請對照圖示閱讀相關重點函數,應該不難理解。

現在,我們對 Python 垃圾回收機制有了框架上的把握,但對檢測垃圾對象的方法還知之甚少。垃圾對象識別是垃圾回收工作的重中之重,Python 是如何解決這一關鍵問題的呢?

 

責任編輯:武曉燕 來源: 小菜學編程
相關推薦

2010-09-25 15:26:12

JVM垃圾回收

2010-10-13 10:24:38

垃圾回收機制JVMJava

2017-08-17 15:40:08

大數據Python垃圾回收機制

2017-06-12 17:38:32

Python垃圾回收引用

2017-03-03 09:26:48

PHP垃圾回收機制

2010-09-25 15:33:19

JVM垃圾回收

2009-06-23 14:15:00

Java垃圾回收

2021-11-05 15:23:20

JVM回收算法

2010-09-16 15:10:24

JVM垃圾回收機制

2011-07-04 16:48:56

JAVA垃圾回收機制GC

2011-06-28 12:39:34

Java垃圾回收

2015-06-04 09:38:39

Java垃圾回收機

2011-07-04 13:12:04

JavaScript

2011-01-18 14:06:58

JavaScriptweb

2009-12-09 17:28:34

PHP垃圾回收機制

2021-12-07 08:01:33

Javascript 垃圾回收機制前端

2023-03-26 22:48:46

Python引用計數內存

2011-12-26 09:50:05

.NET垃圾回收

2010-09-26 11:22:22

JVM垃圾回收JVM

2024-02-22 17:15:22

JS垃圾回收機制
點贊
收藏

51CTO技術棧公眾號

欧美国产中文高清| 久久久久久噜噜噜久久久精品| 欧美日韩高清在线观看| 欧美一级片免费播放| 日韩精品卡通动漫网站| 黄色成人在线| 国产乱码精品一区二区三区四区| 亚洲欧美国产高清| 国产精品扒开腿做爽爽爽视频| 三大队在线观看| 成人精品一区二区三区校园激情| 美日韩中文字幕| 天天影视色香欲综合网老头| 国产精品日韩欧美| 国产精品99精品无码视亚| 男人天堂资源在线| 亚洲成人精品| 欧美性生活大片视频| 成人在线中文字幕| 91在线国产福利| 亚洲另类欧美日韩| 欧美一区二区网站| a在线免费观看| 波多野结衣av一区二区全免费观看 | 天堂网视频在线| 欧美一级电影免费在线观看| 精品国产一区二区三区小蝌蚪| 夜夜狠狠擅视频| 欧洲精品二区| 日本不卡在线视频| 精品久久五月天| 天堂精品视频| 亚欧视频在线观看| 伊人久久大香| 国产亚洲1区2区3区| 九九热精品视频| 香蕉网在线播放| 国产精品一区二区精品| 2023国产精品视频| 久久手机免费视频| 日韩不卡一二三| 视频免费一区| 精品无码三级在线观看视频| 亚洲偷欧美偷国内偷| 国产原创popny丨九色| 亚洲国产精品久久久久爰性色| 西西人体一区二区| 亚洲精品久久7777777| 国产九九在线观看| 欧洲亚洲两性| 久久久久成人黄色影片| 欧美激情视频免费观看| 欧美精品日韩在线| 日韩精品免费观看视频| 国产日韩亚洲欧美综合| 国产传媒一区二区三区| 久久这里只有精品国产| 亚洲精品一二三**| 精品福利在线视频| 青青草原网站在线观看| 三级网站免费观看| 国产精品综合久久| 18性欧美xxxⅹ性满足| 强乱中文字幕av一区乱码| 99国产精品久久一区二区三区| 亚洲综合免费观看高清完整版在线| 亚洲欧美国产不卡| 国产又爽又黄又嫩又猛又粗| 欧美天天在线| 色妞久久福利网| 久久久精品高清| 国产精品久久久久久妇女| 成人精品一区二区三区中文字幕| 欧美激情成人在线视频| 日韩一级片大全| 国产精品nxnn| 欧美在线free| 玩弄japan白嫩少妇hd| 国产精品四虎| 国产午夜精品一区二区三区四区| 国产不卡一区二区三区在线观看| 精品久久国产视频| 一本色道88久久加勒比精品| 久久久免费在线观看| 在线免费播放av| 国产亚洲欧美日韩精品一区二区三区 | 国产精品美女久久福利网站| 国产成人精品免高潮费视频| 天堂av网手机版| 熟女俱乐部一区二区| 卡通欧美亚洲| a级片在线播放| 久久人人爽人人| 国产主播一区二区三区| 韩国欧美国产1区| 欧美国产第一页| 国产无遮挡又黄又爽| 亚洲综合图色| 国产亚洲精品一区二区| 黄色片视频免费观看| 久久影视三级福利片| 在线观看区一区二| 免费的一级黄色片| 粉嫩av一区| 国产精品久久久久久久久久免费看| 国产乱码精品一区二区三区卡 | 色呦哟—国产精品| 麻豆国产精品va在线观看不卡| 99热精品免费| 国产亚洲一区在线| 日韩在线观看免费高清| 永久免费未满蜜桃| 91精品福利观看| 欧美mv日韩mv国产| 人妻体内射精一区二区| 欧美freesextv| 精品综合久久久久久97| 欧美黑人一级片| 国产精品久久久久久模特 | 在线电影av不卡网址| 中国免费黄色片| 精品国产一区二区三区久久久樱花| 欧美成人三级视频网站| 国产伦精品一区二区三区视频网站| 美女网站色91| 久久久久久久久久婷婷| 日韩在线播放中文字幕| 国产成人在线影院| 色狠狠久久av五月综合|| av在线app| 日韩欧美在线视频日韩欧美在线视频 | 波多野结衣一二三区| 亚洲精品大片| 亚洲精品电影在线| 久艹在线观看视频| 亚洲影院在线| 成人蜜桃视频| 在线观看黄av| 亚洲国产岛国毛片在线| 久久久久久日产精品| 亚洲动漫在线观看| 国产一区二区三区四区视频| 日本在线www| 久久九九国产精品| 国产一线二线三线女| 午夜成人鲁丝片午夜精品| 欧美激情一区二区三区不卡 | 午夜免费福利在线| 欧美精品中文字幕亚洲专区| 亚洲欧美在线免费| 国产熟妇搡bbbb搡bbbb| 欧美黄色一区| 欧美成年人视频网站欧美| 伊人成人在线观看| 久草这里只有精品视频| 成人欧美在线观看| 成人av毛片| 日本久久电影网| 人妻精品久久久久中文字幕| 亚洲黄色精品| 久久久噜噜噜久久久| 91精东传媒理伦片在线观看| 国产欧美在线观看一区| 91看片就是不一样| 久久99久久人婷婷精品综合 | 中文字幕日韩精品在线观看| 久操精品在线| 欧美日韩卡一卡二| 国产女主播喷水高潮网红在线| 黄色亚洲免费| 日韩在线精品一区| 亚洲午夜精品一区| 国产电影一区二区在线观看| 在线看国产一区二区| 久久久欧美精品| av观看在线免费| 亚洲视频香蕉人妖| 想看黄色一级片| 亚洲综合色网| 成人免费在线看片| 成人免费网站观看| 日韩精品在线观看视频| 男人天堂av在线播放| 国产视频亚洲色图| 久热精品在线播放| 亚洲国产一成人久久精品| 亚洲一区免费网站| 爱情岛论坛亚洲品质自拍视频网站 | 国产日韩精品电影| 高潮毛片又色又爽免费| 久久激情综合| 日韩av电影免费在线| 米奇精品一区二区三区| 狠狠躁夜夜躁人人躁婷婷91| 鲁大师私人影院在线观看| 宅男噜噜噜66国产日韩在线观看| 精品一区二区三区国产| 欧美13一16娇小xxxx| 日韩一区二区三区在线视频| 欧美xxxx日本和非洲| 艳女tv在线观看国产一区| av免费精品一区二区三区| 中文字幕在线官网| 少妇高潮 亚洲精品| av在线资源观看| 精品国产乱码久久久久久虫虫漫画| 国产精品一二三区在线观看| 一区二区三区在线电影| 成人黄色在线免费观看| 日本不卡网站| 91精品啪在线观看国产60岁| 国产一级一级片| 久久精品人人做人人综合| 亚洲一区精品视频在线观看| 亚洲精选在线| 在线看视频不卡| 51vv免费精品视频一区二区| 欧美又大粗又爽又黄大片视频| 91免费在线| 亚洲国产另类久久精品| 亚洲网站在线免费观看| 午夜伊人狠狠久久| 成年人性生活视频| 香蕉成人久久| 欧美交换配乱吟粗大25p| 午夜先锋成人动漫在线| 亚洲一区久久久| 69堂免费精品视频在线播放| 欧美精品久久一区二区| 日本免费在线视频| 欧美精品一区二区三区视频| 艳妇乳肉豪妇荡乳av无码福利| 一区二区三区欧美亚洲| 三区四区在线观看| 91色porny在线视频| 少妇精品无码一区二区| 日av在线不卡| 日韩av一二三四| 中文日韩在线| 国产精品igao激情视频| 不卡在线一区| 国产精品一区二区三区不卡| 亚洲伊人精品酒店| 99久久综合精品| 一个色综合网| 亚洲永久免费av| 性色av蜜臀av色欲av| 爽好久久久欧美精品| 午夜精品福利在线观看| 中文字幕日日夜夜| 午夜伦理一区二区| 国产三级国产精品国产国在线观看| 久久久三级国产网站| 偷偷色噜狠狠狠狠的777米奇| 国产一区二区视频在线| 亚洲欧美国产中文| 蜜臂av日日欢夜夜爽一区| 四虎永久在线精品无码视频| 在线免费高清一区二区三区| 久久综合久久综合亚洲| 中文字幕不卡一区| 亚洲第一狼人社区| 欧美一区二区三级| 欧美激情图片小说| 国产精品久久三区| 国产91丝袜美女在线播放| 99re6这里只有精品视频在线观看| 99re在线视频观看| 男女在线观看视频| 久久综合伊人77777蜜臀| 日本高清中文字幕在线| 一区三区二区视频| 天堂v视频永久在线播放| 亚洲成人免费视频| 麻豆成人在线视频| 亚洲午夜成aⅴ人片| 91久久免费视频| 2022国产精品视频| 波多野结衣办公室33分钟| 91在线视频官网| 中文字幕丰满乱子伦无码专区| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 久久婷婷久久一区二区三区| 91精彩刺激对白露脸偷拍| 国产午夜精品久久久久久久| 黄色av免费播放| 日韩一区中文字幕| 久久久美女视频| 午夜欧美在线一二页| 麻豆久久久久久久久久| 日本道色综合久久| 国产情侣小视频| 91久久香蕉国产日韩欧美9色| 91视频免费网址| 日本韩国视频一区二区| 涩涩视频在线观看| 欧美一二三区在线| 特黄视频在线观看| 原创国产精品91| 新版中文在线官网| 热久久这里只有精品| 国产激情久久| 99久热re在线精品996热视频| 久久九九热re6这里有精品| 区一区二区三区中文字幕| 91一区二区| 阿v天堂2017| 久久狠狠亚洲综合| 又黄又色的网站| 久久久精品免费观看| 国产一二三区精品| 好吊成人免视频| 国产精品人人妻人人爽| 日韩激情视频在线播放| 老司机在线看片网av| 欧美肥臀大乳一区二区免费视频| 欧美gv在线观看| 国产精品高精视频免费| 91精品国产自产在线丝袜啪| 日本不卡二区高清三区| 狠色狠色综合久久| 天堂在线资源视频| 成人动漫视频在线| 黄色香蕉视频在线观看| 高潮白浆女日韩av免费看| 国产高清第一页| 一区二区三区黄色| www视频在线观看| 91网站在线看| 国精一区二区| 日韩极品视频在线观看| 美女mm1313爽爽久久久蜜臀| 中文成人无字幕乱码精品区| 亚洲免费观看在线视频| www.av88| 日韩久久精品成人| 天天干在线视频论坛| 国产噜噜噜噜噜久久久久久久久| 欧美aaaaa级| 欧美这里只有精品| 午夜在线视频观看日韩17c| 69xxx免费视频| 中文字幕免费观看一区| 日韩黄色在线播放| 精品久久一区二区三区| 在线中文字幕-区二区三区四区| 国产精品无av码在线观看| 亚洲婷婷影院| 国产中文字幕免费观看| 成人午夜av在线| 免费又黄又爽又色的视频| 欧美男生操女生| a视频网址在线观看| 国产精品9999| 亚洲素人在线| 久热免费在线观看| 91丝袜呻吟高潮美腿白嫩在线观看| 久久综合色综合| 欧美videos中文字幕| 亚洲国产精品精华素| 成人有码在线播放| 婷婷精品进入| 成人免费播放视频| 国产福利一区二区三区| 99热99这里只有精品| 欧美日韩视频不卡| av大片在线播放| 国产精品免费一区豆花| 欧美wwwww| www.久久91| 亚洲色图第一区| 午夜精品一二三区| 欧美劲爆第一页| 亚洲免费成人av在线| 欧美精品一区二区三区免费播放| 国产丝袜欧美中文另类| 丰满人妻一区二区三区四区| 中文字幕视频一区二区在线有码| 成人精品国产| 中文字幕一区二区三区最新| 国产乱码精品1区2区3区| 欧美激情一区二区视频| 精品国产一区二区三区久久影院| 999av小视频在线| 国产精品电影在线观看| 欧美日韩有码| 三级性生活视频| 亚洲午夜免费电影| 青青草视频免费在线观看| 国产suv精品一区二区三区88区| 精品视频久久| 午夜啪啪小视频| 亚洲国产精品久久久久婷婷884| 天堂а√在线8种子蜜桃视频| 国产精品久久久久国产a级| 综合久久婷婷| 色噜噜在线观看| 欧美日韩精品一区二区天天拍小说 | 欧美高清www午色夜在线视频| 在线不卡日本v二区707|