美文网首页
python中的内存管理机制

python中的内存管理机制

作者: lxmm_ydl | 来源:发表于2018-04-02 18:20 被阅读0次

1.何为引用

id()方法:

id(obj, /)

    Return the identity of an object.

     返回一个对象的标识(地址)

    This is guaranteed to be unique among simultaneously existing objects.

    (CPython uses the object's memory address.)

代码:

a = 1

b = 1

print(id(a))

print(id(b)) 

print(a is b)

运行结果:

1410343632

1410343632

True

缓冲区:Python中对比较小的对象进行了缓存,在使用的时候会首先到缓冲池中查询,

如果有,就不再去开辟内存空间,对于int类型的数据,这个范围是-5~256

代码:

a = 1000

b = 1000

print(a is b)

问题:在cmd中执行结果为False,在pycharm中执行结果为True

原因:在cmd中编写代码,是交互式执行的,每一段代码都作为一个独立的代码块,而在编译器或记事本中

(存储为.py形式的),是脚本式执行的,一个文件作为一个代码块,在运行的时候,如果发现这个代码块中已经为这个对象

开辟过内存空间,就会直接引用它,而不会重新开辟内存空间

2.引用计数机制

引用计数:一个对象身上的引用数目

当一个对象的引用计数为0的时候,证明没有其他对象引用它,这时候就可以释放掉它占用的内存空间

,完成垃圾回收。

代码1:

from sys import getrefcount

a = 10

b = 10

print(id(a))

print(id(b))

print(getrefcount(a))#打印a的引用计数

print(getrefcount(b))#打印b的引用计数

运行结果:

590126862000

590126862000

5

5

代码2:

from sys import getrefcount

print("函数执行前引用计数:{}".format(getrefcount(1000)))

def test():

    a = 1000

    print("函数中引用计数:{}".format(getrefcount(1000)))

print("函数执行后引用计数:{}".format(getrefcount(1000)))

test()

运行结果:

函数执行前引用计数:3

函数执行后引用计数:3

函数中引用计数:4

优点:实时性,当没有人引用这个对象的时候,就会立即释放掉它占用的内存

缺点:循环引用

循环引用

代码:

a = []

b = []

a.append(b)

b.append(a)

print(a)

print(b)

运行结果:

[[[...]]]

[[[...]]]

问题:如果两个对象相互引用的话,那么即使没有外部对象引用他们,他们的引用计数也不为0,这就造成了

永远也无法释放他们所占空间,几乎等同于内存泄漏。

3.标记-清除

标记 - 清除:

为了解决循环引用的问题,python采用了标记-清除的垃圾回收机制,当两个对象引用计数都为1,但是他们之间

只存在相互的引用,这时候我们就认为这两个对象没有被外部对象引用,可以将他们占用的内存空间释放

过程:如果A,B相互引用,那么从A的角度来看,他有一个对B的引用,所以将B的引用计数-1,反过来,B有一个对A的引用

所以A的引用也-1。

优点:

可以解决循环引用的问题

问题:

如果A对B有一个引用,但是B对A没有引用,这时候采用标记-清除机制,A和B的引用计数都-1,A可以正常回收内存

但是,B 会因此有一个悬空引用。

循环垃圾回收器:

垃圾回收机制中专门负责确保释放循环引用对象。

4.内存结构

 内存池:

用户管理小块内存的申请和释放

小块内存:小于256b

小块内存申请时,PyMem_Malloc直接在内存池中申请内存

大于256b时,会调用malloc方法

相关文章

网友评论

      本文标题:python中的内存管理机制

      本文链接:https://www.haomeiwen.com/subject/qwvxhftx.html