加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

Python内存管理机制

发布时间:2020-12-17 01:25:03 所属栏目:Python 来源:网络整理
导读:一、python内存 因为要调用while循环,循环内有temp变量,不清楚python是否会在每一轮循环结束后自动释放temp内存空间,做了一个内存测试,发现无论temp = none,还是del temp,只能销毁变量,无法完全释放内存空间。注:红色部分标出相同内存id。 >> for i

一、python内存

因为要调用while循环,循环内有temp变量,不清楚python是否会在每一轮循环结束后自动释放temp内存空间,做了一个内存测试,发现无论temp = none,还是del temp,只能销毁变量,无法完全释放内存空间。注:红色部分标出相同内存id。

>> for i in range(3):
    temp = i
    print temp,id(temp)
0 36666732

2 36666708
>> for i in range(4,7):
temp = i
print temp,id(temp)
temp = None
4 36666684

6 36666660
>> for i in range(7,10):
    temp = i
    print temp,id(temp)
    del temp
7 36666648

9 36666624
>> a = 1
>>> id(a)
36666720
>> b = 5
>>> id(b)

>> c = 8
>>> id(c)
36666636
测试完毕后删除c可以看到,变量c和temp确实被销毁,只是他们指向的引用值仍然会在内存中存在。直至窗口关闭才自动释放,人工无法干预。
>> del c

>> id(c)

Traceback (most recent call last):
File "<pyshell#14>",line 1,in
id(c)
NameError: name 'c' is not defined

id(temp)

Traceback (most recent call last):
File "<pyshell#15>",in
id(temp)
NameError: name 'temp' is not defined

id(5)
36666672
id(10)
36666612
id(100000)
41708736
id("1234")
46118528
d = "1234"
id(4)
36666684



二、内存池机制

查看了相关的博客,更深一步了解python内存机制

<p style="color:rgb(51,51,51);font-family:verdana,Arial,Helvetica,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">Python的内存机制以金字塔行,-1,-2层主要有操作系统进行操作,


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">  第0层是C中的malloc,free等内存分配和释放函数进行操作;


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">  第1层和
<span style="line-height:1.8;font-family:'Microsoft YaHei';">第2层是内存池,有Python的接口函数<span class="n" style="line-height:1.8;">PyMem_Malloc
函数实现,当对象小于256K时有该层直接分配内存;


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">  第3层是最上层,也就是我们对Python对象的直接操作;


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">在 C 中如果频繁的调用 malloc 与 free 时,是会产生性能问题的.再加上频繁的分配与释放小块的内存会产生内存碎片. Python 在这里主要干的工作有:


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">  如果请求分配的内存在1~256字节之间就使用自己的内存管理系统,否则直接使用 malloc.


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">  这里还是会调用 malloc 分配内存,但每次会分配一块大小为256k的大块内存.


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">  经由内存池登记的内存到最后还是会回收到内存池,并不会调用 C 的 free 释放掉.以便下次使用.<span style="line-height:1.8;font-family:'Microsoft YaHei';">对于简单的Python对象,例如数值、字符串,元组(tuple不允许被更改)采用的是复制的方式(深拷贝?),也就是说当将另一个变量B赋值给变量A时,虽然A和B的内存空间仍然相同,但当A的值发生变化时,会重新给A分配空间,A和B的地址变得不再相同


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">



<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';"><span style="color:rgb(51,51);font-family:'Microsoft YaHei';font-size:14px;line-height:28.0000019073486px;">而对于像字典(dict),列表(List)等,改变一个就会引起另一个的改变,也称之为浅拷贝


<p style="color:rgb(51,51);font-family:'Microsoft YaHei';font-size:14px;line-height:28.0000019073486px;">



<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">附:


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';color:rgb(255,0);">引用计数增加


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">1.对象被创建:x=4


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">2.另外的别人被创建:y=x


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">3.被作为参数传递给函数:foo(x)


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">4.作为容器对象的一个元素:a=[1,x,'33']


<p style="color:rgb(51,0);">引用计数减少


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">1.一个本地引用离开了它的作用域。比如上面的foo(x)函数结束时,x指向的对象引用减1。


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">2.对象的别名被显式的销毁:del x ;或者del y


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">3.对象的一个别名被赋值给其他对象:x=789


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">4.对象从一个窗口对象中移除:myList.remove(x)


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">5.窗口对象本身被销毁:del myList,或者窗口对象本身离开了作用域。


<p style="color:rgb(51,0);">垃圾回收


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">1、当内存中有不再使用的部分时,垃圾收集器就会把他们清理掉。它会去检查那些引用计数为0的对象,然后清除其在内存的空间。当然除了引用计数为0的会被清除,还有一种情况也会被垃圾收集器清掉:当两个对象相互引用时,他们本身其他的引用已经为0了。


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">2、垃圾回收机制还有一个循环垃圾回收器,确保释放循环引用对象(a引用b,b引用a,导致其引用计数永远不为0)。


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">参考:


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">[1] Python 2.7.8 documentation memory management


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">[2]深入详解python传值问题及内存管理机制-CSDN


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">[3]Python内存池管理与缓冲池设计 - 张知临的专栏


<p style="color:rgb(51,sans-serif;font-size:14px;line-height:28.0000019073486px;">
<span style="line-height:1.8;font-family:'Microsoft YaHei';">[4]理解python变量和内存管理?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读