人生苦短,只谈风月,谈什么垃圾回收 。
文章插图
据说上图是某语言的垃圾回收机制 。。。
我们写过C语言、C++的朋友都知道,我们的C语言是没有垃圾回收这种说法的 。手动分配、释放内存都需要我们的程序员自己完成 。不管是“内存泄漏” 还是野指针都是让开发者非常头疼的问题 。所以C语言开发这个讨论得最多的话题就是内存管理了 。但是对于其他高级语言来说,例如JAVA、C#、Python等高级语言,已经具备了垃圾回收机制 。这样可以屏蔽内存管理的复杂性,使开发者可以更好地关注核心的业务逻辑 。
对我们的Python开发者来说,我们可以当甩手掌柜 。不用操心它怎么回收程序运行过程中产生的垃圾 。但是这毕竟是一门语言的内心功法,难道我们甘愿一辈子做一个API调参侠吗?
1. 什么是垃圾?当我们的Python解释器在执行到定义变量的语法时,会申请内存空间来存放变量的值,而内存的容量是有限的,这就涉及到变量值所占用内存空间的回收问题 。
当一个对象或者说变量没有用了,就会被当做“垃圾“ 。那什么样的变量是没有用的呢?
a = 10000
当解释器执行到上面这里的时候,会划分一块内存来存储 10000 这个值 。此时的 10000 是被变量 a 引用的a = 30000
当我们修改这个变量的值时,又划分了一块内存来存 30000 这个值,此时变量a引用的值是30000 。这个时候,我们的 10000 已经没有变量引用它了,我们也可以说它变成了垃圾,但是他依旧占着刚才给他的内存 。那我们的解释器,就要把这块内存地盘收回来 。
文章插图
2. 内存泄露和内存溢出上面我们了解了什么是程序运行过程中的“垃圾”,那如果,产生了垃圾,我们不去处理,会产生什么样的后果呢?试想一下,如果你家从不丢垃圾,产生的垃圾就堆在家里会怎么样呢?
- 家里堆满垃圾,有个美女想当你的对象,但是已经没有空间给她住了 。
- 你还能住,但是家里的垃圾很占地方,而且很浪费空间,慢慢的,总有一天你的家里会堆满垃圾
内存溢出:程序在申请内存时,没有足够的内存空间供其使用,出现 out of memory
内存泄露:程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光
3. 引用计数前面我们提到过垃圾的产生是因为,对象没有再被其他变量引用了 。那么,我们的解释器究竟是怎么知道一个对象还有没有被引用的呢?
答案就是:引用计数 。python内部通过引用计数机制来统计一个对象被引用的次数 。当这个数变成0的时候,就说明这个对象没有被引用了 。这个时候它就变成了“垃圾” 。
这个引用计数又是何方神圣呢?让我们看看代码
text = "hello,world"
上面的一行代码做了哪些工作呢?- 创建字符串对象:它的值是hello,world,
- 开辟内存空间:在对象进行实例化的时候,解释器会为对象分配一段内存地址空间 。把这个对象的结构体存储在这段内存地址空间中 。
typedef struct_object {int ob_refcnt;struct_typeobject *ob_type;} PyObject;
熟悉c语言或者c++的朋友,看到这个应该特别熟悉,他就是结构体 。这是因为我们Python官方的解释器是CPython,它底层调用了很多的c类库与接口 。所以一些底层的数据是通过结构体进行存储的 。看不懂的朋友也没有关系 。这里,我们只需要关注一个参数:ob_refcnt
这个参数非常神奇,它记录了这个对象的被变量引用的次数 。所以上面 hello,world 这个对象的引用计数就是 1,因为现在只有text这个变量引用了它 。
①变量初始化赋值:
text = "hello,world"
文章插图
②变量引用传递:
new_text = text
推荐阅读
- Python实现天气查询功能
- 用Python爬取六大平台的弹幕、评论,看这一篇就够了
- Python 中的自然语言处理入门
- 用python帮别人写了个文字识别程序
- 3个提升Python运行速度的方法,很实用
- 手把手教你编写Python抢购脚本
- Python生成遍历暴力破解密码,实战的效果差强人意了
- 详解Python软件安装教程和配置,小白都能看懂的教程,值得收藏
- 被称之为永远的神!就这6个Python爬虫开源项目?
- Python黑科技:暴力破解,你的密码是否安全呢?