Python学习 day12-2021.3.10(Python垃圾回收机制)


Python入门课程系列:


程序的垃圾回收
电脑运行一段时间会变慢,对于这种情况有很多处理方法,比如:
1.关掉不用的程序
2.结束一些进程
3.关闭一些服务
4.重启电脑
我们会发现,重启的效果是最明显的,原因就在于,程序永远不会完美,通过前三张方式无法释放内存资源,而垃圾回收就是为了尽可能的使程序完美。

1. 引用计数机制(重点)

概述:
垃圾回收 Garbage collection (GC)
现在的高级语言如java、c#等,都采用了垃圾收集机制,而不再是c、c++里用户自己管理维护内存的方式。自己管理内存极其自由,可以任意申请内存,但如同一把双刃剑,为大量内存泄漏、悬空指针等bug埋下隐患。
对于一个字符串、列表、类甚至数值都是对象,且定位简单易用的语言,自然不会让用户去处理如何分配回收内存的问题。
python里也同java一样采用了垃圾回收机制,不过不一样的是:python采用的是引用计数机制为主,标记-清除分代收集两种机制为辅的策略。

引用计数原型:
python里每个东西都是对象,它们的核心就是一个结构体:PyObject

PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加 ,但引用它的对象被删除,它的ob_refcnt就会减少。


当引用计数为0时,该对象生命就结束了。

import sys #导入系统模块
a=[]
print(sys.getrefcount(a)) #通过sys.getrefcount函数查看引用的数量
#2
b=a
print(sys.getrefcount(a)) #print执行完就会释放掉
#3
引用计数优点:
  1. 简单
  2. 实时性:一旦没有引用,内存就直接释放了。不用像其他机制需要等到特定时机。实时性还带来一个好处:处理回收内存的时间分摊到了平时
引用计数缺点:
  1. 维护引用计数会耗费资源
  2. 循环引用
list1=[]
list2=[]
list1.append(list2)
list2.append(list1)

list1和list2相互引用,如果不存在其他对象对它们的引用,list1和list2的引用计数也仍然为1,所占的内存永远无法被回收,这将是致命的。
对于如今的强大软件,缺点1尚可接受。但是循环阴影导致内存泄露,注定python还将引入新的回收机制(标记清除和分代收集)。

2. Python中的循环数据结构及引用计数(难点)

import sys
import psutil 
import os
def showMemSize(tag):
    pid=os.getpid() #得到进程id
    p=psutil.Process(pid) #通过进程id得到进程对象
    info=p.memory_full_info() #进程占用的内存信息
    memory=info.uss/1024/1024 #进程占用的内存大小,将字节转化为MB
    print('{} memory used:{}MB'.format(tag,memory))
    pass
#验证循环引用的情况
def func():
    showMemSize('初始化')
    a=[i for i in range(1000000)]
    b=[i for i in range(1000000)]
    a.append(b)
    b.append(a)
    showMemSize('创建列表对象a b之后')
    print(sys.getrefcount(a))
    print(sys.getrefcount(b))
    pass
func()
showMemSize('完成时候的')
# 初始化 memory used:5.74609375MB
# 创建列表对象a b之后 memory used:88.43359375MB
# 3
# 3
#完成时候的 memory used:88.47265625MB
import sys
import psutil
import os
import gc
def showMemSize(tag):
    pid=os.getpid()
    p=psutil.Process(pid)
    info=p.memory_full_info()
    memory=info.uss/1024/1024
    print('{} memory used:{}MB'.format(tag,memory))
    pass
def func():
    showMemSize('初始化')
    a=[i for i in range(1000000)]
    b=[i for i in range(1000000)]
    a.append(b)
    b.append(a)
    showMemSize('创建列表对象a b之后')
    pass
func()
gc.collect() #❗️手动调用垃圾回收功能 
showMemSize('完成时候的')
#初始化 memory used:5.7421875MB
#创建列表对象a b之后 memory used:88.43359375MB
#完成时候的 memory used:9.96484375MB

对循环数据结构 ,引用计数就显得力不从心。这时候就需要引用新的回收机制:标记清除和分代收集。
标记清除机制:
顾名思义,首先标记对象(垃圾检测),然后清除垃圾(垃圾回收)

分代回收建立在标记清除的基础之上。
Python程序运行的时候它将会建立一定数量的“浮点数垃圾”,python的GC不能够处理未使用的对象因为应用计数值不会到零。这也是为什么python要引用Generation GC算法的原因!Python使用一种不同的链表来持续追踪活跃的对象,python内部的C代码将其称为零代(Generation Zero)。每次当你创建一个对象或者其他什么值的时候,python就会将其加入零代链表。

Python中的GC阈值

3. Python中的GC模块(重点)

python中垃圾回收是以引用计数为主,分代收集为辅。

  • GC负责的主要任务:
    1.为新生成的对象分配内存
    2.识别那些垃圾对象
    3.从垃圾对象那里回收内存
  • 导致引用计数+1的情况:
    1.对象被创建
    2.对象被引用
    3.对象被作为一个参数,传入到一个函数中
    4.对象作为一个元素,存储在容器中
  • 导致引用次数-1的情况:
    1.对象的别名被显式销毁
    2.对象的别名被赋予新的对象
    3.一个对象离开它的作用域。例如f函数执行完毕时,func函数中的局部变量(全部变量不会)
    4.对象所在的容器被销毁或从容器中移除对象
  • 有三种情况会触发垃圾回收:
    1.当gc模块的计数器达到阈值的时候,自动回收垃圾
    2.调用gc.collect(),手动回收垃圾
    3.程序退出的时候,python解释器来回收垃圾

4. Python内存优化

5. Python pep8规范(重点)

6. Python命令行参数(难点)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容