前言本文的文字及圖片來源於網路,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯繫我們以作處理。 作者:醍醐三葉 關於python的存儲問題, (1)由於python中萬物皆對象,所以python的存儲問題是對象的存儲問題,並且對於每個對象,python會分配一塊記憶體空間去 ...
前言
本文的文字及圖片來源於網路,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯繫我們以作處理。
作者:醍醐三葉
關於python的存儲問題,
(1)由於python中萬物皆對象,所以python的存儲問題是對象的存儲問題,並且對於每個對象,python會分配一塊記憶體空間去存儲它
(2)對於整數和短小的字元等,python會執行緩存機制,即將這些對象進行緩存,不會為相同的對象分配多個記憶體空間,如果對我講的還不懂,說明你基礎學的還不是和很好,可以去小編的Python交流.裙 :一久武其而而流一思(數字的諧音)轉換下可以找到了,裡面很多最新Python精講的教程項目。
(3)容器對象,如列表、元組、字典等,存儲的其他對象,僅僅是其他對象的引用,即地址,並不是這些對象本身
關於引用計數器
(1)一個對象會記錄著引用自己的對象的個數,每增加一個引用,個數加一,每減少一個引用,個數減一
(2)查看引用對象個數的方法:導入sys模塊,使用模塊中的getrefcount(對象)方法,由於這裡也是一個引用,故輸出的結果多1
(3)增加引用個數的情況:1.對象被創建p = Person(),增加1;2.對象被引用p1 = p,增加1;3.對象被當作參數傳入函數func(object),增加2,原因是函數中有兩個屬性在引用該對象;4.對象存儲到容器對象中l = [p],增加1
(4)減少引用個數的情況:1.對象的別名被銷毀del p,減少1;2.對象的別名被賦予其他對象,減少1;3.對象離開自己的作用域,如getrefcount(對象)方法,每次用完後,其對對象的那個引用就會被銷毀,減少1;4.對象從容器對象中刪除,或者容器對象被銷毀,減少1
(5)引用計數器用法:
import sys class Person(object): pass p = Person() p1 = p print(sys.getrefcount(p)) p2 = p1 print(sys.getrefcount(p)) p3 = p2 print(sys.getrefcount(p)) del p1 print(sys.getrefcount(p))
多一個引用,結果加1,銷毀一個引用,結果減少1
(6)引用計數器機制:利用引用計數器方法,在檢測到對象引用個數為0時,對普通的對象進行釋放記憶體的機制
關於迴圈引用問題,如果對我講的還不懂,說明你基礎學的還不是和很好,可以去小編的Python交流.裙 :一久武其而而流一思(數字的諧音)轉換下可以找到了,裡面很多最新Python精講的教程項目。
(1)迴圈引用即對象之間進行相互引用,出現迴圈引用後,利用上述引用計數機制無法對迴圈引用中的對象進行釋放空間,這就是迴圈引用問題
(2)迴圈引用形式:
class Person(object): pass class Dog(object): pass p = Person() d = Dog() p.pet = d d.master = p
即對象p中的屬性引用d,而對象d中屬性同時來引用p,從而造成僅僅刪除p和d對象,也無法釋放其記憶體空間,因為他們依然在被引用。深入解釋就是,迴圈引用後,p和d被引用個數為2,刪除p和d對象後,兩者被引用個數變為1,並不是0,而python只有在檢查到一個對象的被引用個數為0時,才會自動釋放其記憶體,所以這裡無法釋放p和d的記憶體空間
關於垃圾回收(底層層面--原理)
(1)垃圾回收的作用:從經過引用計數器機制後還沒有被釋放掉記憶體的對象中,找到迴圈引用對象,並釋放掉其記憶體
(2)垃圾回收檢測流程:
一.任何找到迴圈引用並釋放記憶體:1.收集所有容器對象(迴圈引用只針對於容器對象,其他對象不會產生迴圈引用),使用雙向鏈表(可以看作一個集合)對這些對象進行引用;2.針對每一個容器對象,使用變數gc_refs來記錄當前對應的應用個數;3.對於每個容器對象,找到其正在引用的其他容器對象,並將這個被引用的容器對象引用計數減去1;4.經過步驟3後,檢查所有容器對象的引用計數,若為0,則證明該容器對象是由於迴圈引用存活下來的,並對其進行銷毀
二.如何提升查找迴圈引用過程的性能:由一可知,迴圈引用查找和銷毀過程非常繁瑣,要分別處理每一個容器對象,所以python考慮一種改善性能的做法,即分代回收。首先是一個假設--如果一個對象被檢測了10次還沒有被銷毀,就減少對其的檢測頻率;基於這個假設,提出一套機制,即分代回收機制。
通過這個機制,迴圈引用處理過程就會得到很大的性能提升
關於垃圾回收時機(應用層面--重點)
(1)自動回收:
(2)手動回收:這裡要使用gc模塊中的collect()方法,使得執行這個方法時執行分代回收機制
import objgraph import gc import sys class Person(object): pass class Dog(object): pass p = Person() d = Dog() p.pet = d d.master = p del p del d gc.collect() print(objgraph.count("Person")) print(objgraph.count("Dog"))
其中objgraph模塊的count()方法是記錄當前類產生的實例對象的個數
關於記憶體管理機制的總結(重點)
綜上所述,python的記憶體管理機制就是引用計數器機制和垃圾回收機制的混合機制