python物件記憶體模型

2021-08-19 15:48:08 字數 1979 閱讀 3114

首先介紹一下python物件的記憶體模型,如下圖1所示:

圖1. pyobject物件記憶體模型

上圖可以看到,乙個pyobject必須包含ob_refcntob_type

這兩個屬性

ob_refcnt是這個物件的引用計數,而ob_type則是指向_typeobject結構體的指標,它是python內部的一種特殊物件,它是用來制定乙個物件型別的型別物件,所以上圖中它指向了乙個pytypeobject

在python中,物件機制的核心其實非常簡單,乙個是引用計數,乙個是型別資訊。

我們再來看定長物件none,int,list,其結構如下圖2所示:

圖2.none,int,list物件記憶體模型

上圖可以看到,none物件的記憶體模型是與pyobject一致的;而int物件則是多了乙個ob_ival,這個字段其實就是儲存int真實的value。

問題一:令人奇怪的是,在python中,list其實是乙個可變長的,類似於c++中的vector的資料結構,為什麼它的記憶體模型是定長的呢?

其實它的記憶體模型的字段都是元資料(meta-data),而真正存放陣列資料的是ob_item指向的乙個陣列。

問題二:在pylistobject物件中,有乙個ob_size,而在最後為什麼又有乙個allocated,那麼這兩個變數之間的關係是什麼呢?

其實,ob_sizeallocated都和pylistobject物件的記憶體管理有關,pylistobject所採用的記憶體管理策略和c++中的vector採取記憶體管理策略是一樣的。在每一次需要申請記憶體的時候,pylistobject總會申請一大塊記憶體,這是申請的總記憶體的大小記錄在allocated中,而實際被使用了的記憶體的數量則記錄在了ob_size中。

我們再來看看變長物件的記憶體模型,例如tuple,它的結構如下圖3所示:

圖3.tuple物件記憶體模型

上圖就可以解釋,為什麼tuple在python中使用是乙個定長的list,為什麼在pyobject中卻是變長物件了。

而string的記憶體模型如下圖所示:

圖4.string物件記憶體模型

在建立pystringobject物件時,除了為pystring_object申請記憶體,還有為字元陣列內的元素申請額外的記憶體(綠色填充的字元陣列記憶體)。然後將hash快取值設為-1,將引數str指向的字元陣列內的字元拷貝到pystringobject所維護的空間中,在拷貝過程中,將字元陣列最後的'\0'字元也拷貝了。

上面講述了很多python的基礎資料型別,而這些基礎型別(包括pytypeobject)都是物件(all is object)。每個物件至少包含了ob_refcntob_type兩個字段,如果是32bit的作業系統,那麼他們共是8個位元組。

型別記憶體模型(物件記憶體模型)

型別的記憶體模型的3個問題 1 包含什麼 附加資訊 2 怎麼布局 記憶體對齊 3 使用場景 怎麼使用附加資訊 除了包含結構型別的顯式成員變數外,型別記憶體模型需要解決附加資訊的引入問題 1 附加資訊 opaque 有哪些 型別資訊 函式資訊 繼承資訊 記憶體計數等 2 為什麼有附加資訊 1 解決多型...

物件記憶體模型

物件物件模型 物件在記憶體是如何存放的 存放規則 1.class記憶體對齊規則和struct相同。2.class 成員函式和成員變數分開存放,每個物件有獨享的成員變數 堆疊全域性資料 同一類的所有物件共享同一成員函式 段 3.呼叫成員函式時將物件位址傳遞給成員函式 隱式傳遞 成員函式通過物件位址 t...

python 記憶體模型

python 記憶體模型 1.python變數採用引用語義,每乙個變數名儲存的是實際存放資料的記憶體的位址 01.讀取資料時,x 10,可以認為,通過唯讀指標 位址 訪問資料10所在的記憶體空間,通過變數中存放的位址訪問記憶體只能讀,不能寫 02.寫,需要重新分配一塊記憶體空間,存放新資料,並用新位...