python垃圾回收机制

python中垃圾回收

Python中一切皆对象,一切变量,本质上是对象的一个指针。那么,如何知道一个对象不再被调用了?

当这个对象的引用计数(指针数)为0的时候,说明这个对象不可达,就成了垃圾,需要回收。

import sys, gc

# a引用计数1
a = []
# a引用计数2
print(sys.getrefcount(a))

# b引用计数1
b = []
# 形参也占用,引用计数2
def func(item):
    # 引用计数3
    print(sys.getrefcount(b))

#引用计数4
func(b)

查看应用计数的方式,getrefcount本身也会算一次

查看内存使用情况,下面代码linux下运行

import os
import psutil

def show_memory_info(initial):
    pid = os.getpid()
    p = psutil.Process(pid)
    info = p.memory_full_info()
    memory = info.uss / 1024. / 1024
    print('{} memory_used {} MB', format(initial, memory))
    

def func():
    show_memory_info('start')
    a = [i for i in range(1000000)]
    show_memory_info('after a created')

func()
show_memory_info('end')

引用计数的缺点,循环引用

list1 = []
list2 = []
list1.append(list2)
list2.append(list1)

当出现上面情况的时候,即使不在有对象调用list1、list2引用,引用计数也为1,所占用的内存永远无法被回收,会导致内存泄漏。

import gc, sys

list1 = []
list2 = []
list1.append(list2)
list2.append(list1)

print(sys.getrefcount(list1))
print(sys.getrefcount(list2))

del list1
del list2

# 手动垃圾回收
print(gc.collect())
# 3
# 3
# 2

垃圾回收参考自:https://www.cnblogs.com/franknihao/p/7326849.html

调试内存泄漏

import objgraph

a = [1, 2, 3]
b = [4, 5, 6]

a.append(b)
b.append(a)

objgraph.show_refs([a])

在这里插入图片描述

dot转图片:https://onlineconvertfree.com/zh/

总结

  • python中自带垃圾回收机制
  • 引用计数是其中最简单的实现方式,但不是充分必要条件,循环引用需要手动回收
  • python的自动回收算法包括标记清楚和分代收集,主要针对的是循环引用的垃圾收集
  • 调试内存泄露,objgraph是很好的可视化工具。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值