一、記憶體管理機制
1.由c開發出來的cpython
2.include / objests
3.需要下載python原始碼包
4.Pyobject:float
PyVarObject:
5.在python中所有東西創建物件的時候,內部都會存盤一個資料
// 維護雙向鏈表
struct _object *_ob_next;
struct _object *_ob_prev;
// 應用計數器
Py_ssize_t ob_refcnt;
// 型別
struct _typeobject *ob_type;
如果是有多個元素組成的話,內部會再多維護一個
Py_ssize_t ob_size; /* Number of items in variable part */
6.在創建物件時,如:
操作:
v = 0.3
原始碼內部:
a.開辟記憶體
b.初始化
ob_fval=0.3
ob_type=float
ob_refcnt=1
c.將物件加入到雙向鏈表中 ref_chain
操作:
name = v
原始碼內部:
ob_refcnt+1
操作:
del v
原始碼內部:
ob_refcnt-1
操作:
def fun(arg):
print(123)
fun(name)
原始碼內部:
剛進去:ob_refcnt+1
執行完:ob_refcnt-1
操作:
del name
原始碼內部:
ob_refcnt-1
每次應用計數器減一時,都會檢查是否為0,如果是0則認為他是垃圾,就對它進行回收
記憶體管理機制
Python是由c語言開發,操作都是基于底層的c語言實作的,Python中創建每個物件,內部都會與c語言結構體維護一些值
Pyobject
指標指向上面的資料
指標指向下面的資料
計數器
型別
PyVarObject
PyObject
容量個數
在創建物件時,每個物件至少內部有四個值:雙向鏈表/ob_refcnt/ob_type,之后對記憶體中的資料進行初始化,初始化本質:參考計數器=1,賦值,然后將物件添加到雙向鏈表中,以后再有其他變數執行這個記憶體,則讓參考計數器+1,如果銷毀某個變數,則找到指向的記憶體,將其參考計數器-1
參考計數器如果為零則進行垃圾回收
在內部可能存在快取機制,例如:float/int/list,最開始不會真正銷毀,而是放在free_list的鏈表中,以后在創建同型別的資料時,會先去鏈表中取出物件,然后在對物件進行初始化,
(float記憶體管理中默認快取100個/list記憶體管理中默認快取10個)
二、垃圾回識訓制
參考計數器為主,標記清楚和分代回收為輔
1.參考計數器
參考計數器同上記憶體管理中的描述
參考計數器會出現回圈參考
(1)
a = [1, 2]
b = [4, 5]
a.append(b) # a中的第三個元素指向b,b的計數器發生變化,變成2了
(2)
del a
del b
# 當這種代碼特別多的時候,記憶體的占用也會特別多,記憶體占用特別多的時候會造成記憶體泄漏(溢位)
2.標記清除
標記清除可以用來解決記憶體泄漏的問題
針對那些容器型別的物件,在Python中會將他們單獨放到一個雙向鏈表中,做定期掃描,檢查是否有回圈參考,如果有各自-1,如果-1之后等于0,則直接回收,
3.分代回收
為了減少物件的掃描,將沒有問題的物件讓他放到上一級的鏈表中,默認下一級掃描10次上一級才掃描1次,一共有三代鏈表
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/195929.html
標籤:Python
