前言
本文的文字及圖片來源於網絡,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯系我們以作處理。
關於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的內存管理機制就是引用計數器機制和垃圾回收機制的混合機制