Python深入之python記憶體管理機制(重點)

来源:https://www.cnblogs.com/chengxuyuanaa/archive/2019/12/03/11979857.html

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


您的分享是我們最大的動力!

更多相關文章
  • LinkedList實現原理(JDK1.8) LinkedList底層採用雙向鏈表,如果對鏈表這種結構比較熟悉的話,那LinkedList的實現原理看明白就相當容易。 鏈表通過“指針”將一組零散的記憶體塊串聯起來使用,每一個元素(節點)通過指針指向它的下一個元素,最後一個節點的下一個指向為null,而 ...
  • Java抽象類: 抽象類特點 :抽象類除了不能實例化對象之外,類的其它功能依然存在,成員變數、成員方法和構造方法的訪問方式和普通類一樣。 由於抽象類不能實例化對象,所以抽象類必須被extends [抽象類]方式 繼承才能被使用。 抽象類表示的是一種繼承關係。 (總結就是:抽象類裡面設計跟普通類一樣, ...
  • lua中json和table的互轉,是我們在平時開發過程中經常用到的。比如: 在用lua編寫的伺服器中,如果客戶端發送json格式的數據,那麼在lua處理業務邏輯的時候,必然需要轉換成lua自己的數據結構,如table。此時,就會用到table和json格式的互轉。 在用lua編寫的伺服器中,如果我 ...
  • 先定義消息類型 orders.proto 在GOPATH創建目錄和編譯這個消息類型輸出到該目錄,包名是message 編寫go文件進行序列化和反序列化剛纔生成的包里的類型結構體數據 ...
  • swap(a,b) 用於交換a,b兩個變數的值; max(a,b) 返回a,b中的最大值; min(a,b) 返回a,b中的最小值; abs(x) 返回x的絕對值,x必須是整數; ...
  • ——日拱一卒,不期而至! 你好,我是彤哥,本篇是netty系列的第六篇。 簡介 上一章我們一起學習了Java NIO的核心組件Channel,它可以看作是實體與實體之間的連接,而且需要與Buffer交互,這一章我們就來學習一下Buffer的特性。 概念 Buffer用於與Channel交互時使用,通 ...
  • 前言 "上文" 我們介紹了JDK中的線程池框架 。我們知道,只要需要創建線程的情況下,即使是在單線程模式下,我們也要儘量使用 。即: 但是,在 "《阿裡巴巴Java開發手冊》" 中有一條 【強制】線程池不允許使用 Executors 去創建,而是通過 ThreadPoolExecutor 的方式,這 ...
  • PyCharm 是一種 Python IDE,可以幫助程式員節約時間,提高生產效率。那麼具體如何使用呢?本文從 PyCharm 安裝到插件、外部工具、專業版功能等進行了一一介紹,希望能夠幫助到大家。 機器之心之前也沒系統地介紹過 PyCharm,怎樣配置環境、怎樣 DeBug、怎樣同步 GitHub ...
一周排行
  • Consul是HashiCorp公司推出的開源工具,Consul由Go語言開發,部署起來非常容易,只需要極少的可執行程式和配置文件,具有綠色、輕量級的特點。Consul是`分散式`的、`高可用`的、 `可橫向擴展`的用於實現分散式系統的服務發現與配置。 ...
  • Blazor的哪個特點, 可以讓程式員快速完成任務? 這隨筆講解的是使用代碼上下文來節約代碼, 讓驗證碼機制變得更加簡易. ...
  • 在C#中,struct和class都是用戶定義的數據類型,struct和class有許多不同之處,但主要的區別是: Class是引用類型,它保存在堆上並且能夠被垃圾回收;然而stuct是值類型,它保存在棧上或者內嵌在它的包含類型之中。因此,從總體上來說struct比class節省記憶體。 下圖是Cla ...
  • 這篇文章,我將帶領大家學習ASP.NET Core中的launchSettings.json文件。為了學習它,我們打開之前建的空白模板的ASP.NET Core項目。 從上面的圖片中你可以看到,我們項目的屬性中有一個launchSettings.json文件。那麼我們來一起學習這個重要的文件吧。la... ...
  • [TOC] 都是迭代,為啥我一定要用foreach ​ 問題起源於本人的一個練手的撲克牌程式:洗完牌之後要發給場上的三人。 ​ 只發給單個人的時候用 foreach 迴圈一下就好了,但三個人就有點麻煩了。 ​ 牌組用list保存你可能會想到這樣寫: 對於字典,可以使用 : 可能各位早會這樣弄了,讓各 ...
  • 首先以Winform項目開發舉例 1.完整的學習計劃 2.對於學習內容分類 3.良好的學習習慣 4.項目實踐 學習計劃 1.基礎篇 2.提高篇 3.應用篇 內容分類 1.語法 2.控制項 3.業務邏輯 學習習慣 1.時間安排 2.進度安排 3.記錄筆記 4.練習寫代碼 項目實踐 1.實現頁面展示 2. ...
  • 在進行 Asp.NetCore.MVC 文件上傳時,後臺無法正常讀取文件流保存,出現:Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead. 查找資料,發現需要 ...
  • 在這篇文章中,我將詳細介紹在ASP.NET Core中使用appsettings.json文件的重要性。這篇文章,我將詳細介紹下麵幾個問題:在ASP.NET Core應用程式中,有哪些不同的配置資源可用呢?什麼是ASP.NET Core appsetting.json文件?在ASP.NET Core ...
  • 這篇文章中,我將帶領大家一起詳細學習:ASP.NET Core Middleware Components.這篇文章中,我將詳細討論下麵幾個問題:什麼是ASP.NET Core 中的中間件組件?ASP.NET Core應用程式中,在哪裡來使用中間件組件?怎樣來配置ASP.NET Core 應用程式中... ...
  • 參考 ABP設計UI菜單欄的源碼分析,抽出了ABP這塊自定義擴展的實現。在ABP的源碼裡面有很多地方都用到了這種設計方式,實現了用戶自定義擴展。 新建一個空的asp.net core項目,新建一個類,源碼: StartUp類源碼: 擴展點:在 中提供用戶自定義擴展點,完美的是下瞭解耦。 參考: "B ...