1. 程式人生 > >Python基礎系列:初識python引用計數與弱引用

Python基礎系列:初識python引用計數與弱引用

寫在前邊:

之前的socket系列就告一段落,主要是對自己所學做一個總結與記錄。

接下來我打算基於libevent寫一個支援併發的HTTP伺服器。因為之前學習群裡大神早就開發過一個同時支援HTTP與WebSocket的伺服器,我看了之後感覺很有興趣,所以才買了本網路程式設計的書來看。我打算參考他的來寫一個精簡版,

只支援HTTP。等寫完了可以分享給大家,雖然不能運用到生產環境,但是我相信學習完原始碼之後對於自己也是一個極大的提升。

接下來進入主題:

先放上例項程式碼:

這裡寫圖片描述

我們建立一個用於測試的x物件,包括一個建構函式和一個解構函式。

第一次初始化x物件,並且用變數a來引用,所以這裡的引用計數就為1。之後通過 getrefcount 來獲取引用數量,這裡變為了2,因為呼叫函式 getrefcount 本身也是對a的一次引用。

接下來通過 weakref.ref() 建立一個弱引用,通過 getrefcount 列印引用計數後,發現計數並沒有改變。

w() is a 這句的意思是判斷這兩個例項是不是完全相同,也就是佔用的記憶體地址是否相同。

然後我們通過 del a 來解除a對x物件的引用,注意這裡del並不是直接回收x物件,而是解除了引用,我們知道一旦一個變數的引用為0的時候就會被回收。所以呼叫del之後x物件被回收。

通過之前的程式碼我們看到,呼叫弱引用的方式為類函式的方式。不過可以使用proxy來改為使用變數名的方式呼叫。

這裡寫圖片描述

到這裡我相信對於弱引用的使用方式肯定都掌握了。但是弱引用到底有什麼作用呢?

與很多其它的高階語言一樣,Python也有垃圾回收機制。每個物件都有一個引用計數,當這個計數為0的時候才能夠安全地銷燬這個物件。

由於一次僅能有一個物件被回收,引用計數無法回收迴圈引用的物件。一組相互引用的物件若沒有被其它物件直接引用,並且不可訪問,則會永久存活下來。

一個應用程式如果持續地產生這種不可訪問的物件群組,就會發生記憶體洩漏。

所以弱引用很適合處理這種迴圈引用的場景。

這裡寫圖片描述