一、背景

之前能说个大概,python垃圾回收机制,设计到细节就不太清楚。
如同刚毕业的少年,出厂自带三年工作经验。做过啥啥.. 一问细节,阿西吧..
不要问我怎么知道滴.. 哈哈!!!

- 提高自己的计算机基础
- 重要的是面试(曾被问到三次)
- 装逼用

二、垃圾回收分类

1. 引用计数
2. 标记清楚
3. 分代回收

三、python垃圾回收机制

1. 引用计数
  • 引用计数:
每增加一个引用,这个对象的引用计数会自动+1
每减少一个引用,这个对象的引用计数会自动-1

当一个对象 如果被引用+1 删除一个引用 -1 0被自动释放
  • 引用计数增加场景+1
1. 第一次创建对象时 p1 = Persion()
2. 对象被再次饮用时 p2 = p1
3. 对象被当作参数,传入到一个函数当中
4. 对象作为一个元素,存在容器中 li = [ p1 ]
  • 引用计数-1场景
1. 对象的别名被显式销毁   del p1
2. 对象的别名被赋予新的对象 p1 = 123
3. 一个对象离开了他的作用域 一个函数执行完毕时
例: 在函数内部定义一个局部变量, 当这个函数执行完毕时, 它内部引用的函数对象会再次被释放
4. 对象所在的容器被销毁, 或从容器中删除 例: 加1 的第四种
  • 引用计数查看
import sys
sys.getrefcount(obj) - 1
2. 标记清楚
  • 标记清除​:从经历过引用计数机制仍未释放的对象中,找到循环引用干掉相关对象
  • 标记清除底层机制​:
1. 收集所有的容器对象, 通过一个双向链表进行引用 (容器对象:列表、元祖、字典 )
2. 针对于每一个容器对象,通过一个变量gc_refs 来记录当前对应的引用计数
3. 找到每个容器对象,找到它引用的容器对象,并将这个容器的引用计数-1
4. 经过步骤3之后, 如果一个容器对象的引用计数为0, 就代表该对象可以被回收了, 循环引用导致其活到现在的
3. 分代回收(参考java机制)
  • 分代回收机制
1. 默认一个对象被创建出来后, 属于年轻代
2. 如果经历过年轻代垃圾回收后依然存活,则分配到老年代
3. 垃圾回收的周期顺序为 年轻代垃圾回收一定次数,会出发年轻代与老年代回收
年轻代垃圾回收一定次数, 会出发 年轻代、老年代、持久代回收

4. 垃圾回收器中, 新增的对象个数-消亡的对象个数达到一定阈值,才会触发垃圾检测
  • 查看分代回收 查看相关参数​:
import gc
print(gc.get_threshold())
gc.set_threshold(700, 10, 5)
参数1 阈值
参数2 当年轻代被检测10时 触发年轻代和老年代检测
参数3 当老年代被检测5时 触发年轻代和老年代检测和老年代的检测
  • 垃圾回收时机:
  1. 自动回收
达到垃圾回收的阈值: 垃圾回收器中, 新增的对象个数和释放对象个数之差达到某个阈值

gc.enable() 开启垃圾回收机制(默认开启)
gc.disable() 关闭来及回收机制
gc.isenable() 判断是否开启垃圾回收机制
  1. 手动回收
gc.get_threshold()  获取自动回收阀值  
gc.set_threshold() 设置自动回收阀值

四、 java 垃圾回收机制

  • 年轻代(Young Generation)​​
    所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。
  • 年老代(Old Generation)​​
    在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。
  • 持久代(Permanent Generation)​​
    用于存放静态文件,如Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate 等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类

注:​​​b站功夫好呀,b站功夫棒.. 我在b站学的 ​