詳解python的記憶體分配機制

2022-09-25 18:03:08 字數 3655 閱讀 4126

作為乙個例項,讓我們建立四個變數並為其賦值:

variable1 = 1

variable2 = "abc"

variable3 = (1,2)

variable4 = ['a',1]

#列印他們的ids

print('variable1: ', id(variable1))

print('variable2: ', id(variable2))

print('variable3: ', id(variable3))

print('variable4: ', id(variable4))

列印結果如下所示:

變數1:1747938368

變數2:152386423976

變數3:152382712136

loizaeasc變數4:152382633160

每個變數都被分配了乙個新的記憶體位址(以整數形式表示)。第乙個假設是,每當我們使用「 =」給變數賦值時,python都會建立乙個新的記憶體位址來儲存變數。這是100%正確的嗎?當然不是!

我將建立兩個新變數(5和6)並使用現有變數的值給它們賦值。

variable5 = variable1

variable6 = variable4

print('variable1: ', id(variable1))

print('variable4: ', id(variable4))

print('variable5: ', id(variable5))

print('variable6: ', id(variable6))

python列印結果:

變數1:1747938368

變數4:819035469000

變數5:1747938368

變數6:819035469000

你注意到,python並未為這兩個變數建立新的記憶體位址嗎?這次,它只是把兩個新變數都指向了現有變數相同的儲存位置。

現在讓我們為變數1設定乙個新值。注意:整數是不可變資料型別。

print('variable1: ', id(variable1))

variable1 = 2

print('variable1: ', id(variable1))

這將列印:

variable1: 1747938368

variable1: 1747938400

這意味著每當我們使用=並將新值給現有變數賦值時,就會在內部建立乙個新的記憶體位址來儲存該變數。讓我們看看它是否成立!

當值是可變資料型別時會發生什麼?variable6是乙個列表,讓我們在列表結尾append乙個值並列印其記憶體位址:

print('variable6:',id(variable6))

variable6.append('new')

print('variable6:',id(variable6))

請注意,變數的記憶體位址保持不變,因為它是可變資料型別,我們僅更新了其元素。

variable6:678181106888

variable6:678181106888

讓我們建立乙個函式並將乙個變數傳遞給它。如果我們在函式內部設定變數的值,它會發生什麼?讓我們評估一下。

def update_variable(variable_to_update):

print(id(variable_to_update))

update_variable(variable6)

print('variable6: ', id(variable6))

請注意,variable_to_update的id指向變數6的id。

這意味著如果我們在函式中更新variable_to_update且variable_to_update是可變資料型別,那麼variable6的值將更新。我們看乙個具體例子:

variable6 = ['new']

print('variable6: ', variable6)

def update_variable(variable_to_update):

variable_to_update.append('inside')

update_variable(variable6)

print('variable6: ', variable6)

這將列印:

variable6:['new']

variable6:['new','inside']

它向我們展示了如何在函式中的更新乙個可變的變數,你可以看到函式類和函式外的可變變數都具有相同的id。

如果我們在函式內給變數賦乙個新值(而不是更新),無論它是不可變的還是可變的資料型別,那麼一旦退出函式,更改將丟失:

print('variable6: ', variable6)

def update_variable(variable_to_update):

print(id(variable_to_update))

variable_to_update = ['inside']

update_variable(variable6)

print('variable6: ', variable6)

variable6:['new']

344115201992

variable6:['new']

現在是乙個有趣的場景:python並不總是為所有新變數建立乙個新的記憶體位址。

最後,如果我們為兩個不同的變數分配乙個字串值,例如「 a」,該怎麼辦它會建立兩個記憶體位址嗎?

variable_nine ="a"

variable_ten ="a"

print('variable9:',id(variable_nine))

print('variable10:',id(variable_ten))

注意,這兩個變數具有相同的記憶體位置:

variable9:792473698064

variable10:792473698064

如果我們建立兩個不同的變數並為其分配乙個長字串值,該怎麼辦:

variable_nine = "a" * 21

variable_ten = "a" * 21

print('程式設計客棧variable9: ', id(variable_nine))

print('variable10: ', id(variable_ten))

這次python為兩個變數建立了兩個不同記憶體位置:

variable9:541949933872

variable10:541949933944

為什麼? 這是因為python啟動時會建立乙個內部值快取,這樣做是為了提供更快的結果。python會為少量整數(如-5到256之間)和較小的字串值分配了少量的記憶體位址。這就是我們示例中的短字串都具有相同id的原因,而長字串的id則不同。

有時我們想檢查兩個物件是否相等。

var1 = "a"&nbsloizaeascp;* 30 

var2 = "a" * 30 

print('var1:',id(var1))#318966315648

print('var2:',id(var2))#168966317364

print('==:', var1 www.cppcns.com== var2)#返回true

print('is:',var1 is var2)#返回false

python記憶體分配機制

python中數值型別是不可變物件,當程式試圖改變資料的值時,程式會重新生成新的資料,而不是改變原來的資料。python函式的引數都是物件的引用,如果在引用不可變物件時嘗試修改物件,程式會在函式中生成新的物件 開闢新的位址空間 函式外被引用的物件則不會被改變。num 1 defadd num num...

C C 記憶體分配機制

1.c語言中的記憶體機制 在c語言中,記憶體主要分為如下5個儲存區 1 棧 stack 位於函式內的區域性變數 包括函式實參 由編譯器負責分配釋放,函式結束,棧變數失效。2 堆 heap 由程式設計師用malloc calloc realloc分配,free釋放。如果程式設計師忘記free了,則會造...

memcached記憶體分配機制

memcached slab allocator分配機制 slab allocator的基本原理是按照預先規定的大小,將分配的記憶體分割成特定長度的塊,以完全解決記憶體碎片問題。slab allocation的原理相當簡單,就是將分配的記憶體分割成各種尺寸的塊 chunk 並把尺寸相同的塊分成組 c...