说明
在 C 语言里,我们需要使用 free 去手动释放内存,在 Python 里面,我们可以使用 del 对象 + gc.collection 来触发垃圾回收。
代码实现
import gc
import os
import psutil
def show_memory_info(hint):
"""
定义一个显示内存情况的函数
:param hint:
:return:
"""
# 获取当前进程的进程号
pid = os.getpid()
# psutil 是一个获取系统信息的库
p = psutil.Process(pid)
info = p.memory_full_info()
memory = info.uss/1024./1024
print(f"{hint} memory used: {memory} MB ")
def main():
show_memory_info("initial")
a = [i for i in range(1000000)]
show_memory_info("after a created")
# 强制手动进行垃圾回收
del a
gc.collect()
show_memory_info("finish")
try:
print(a)
except Exception as e:
print(e)
main()
运行结果:
循环引用导致垃圾回收失败
import gc
import os
import psutil
def show_memory_info(hint):
# 获取当前进程的进程号
pid = os.getpid()
# psutil 是一个获取系统信息的库
p = psutil.Process(pid)
info = p.memory_full_info()
memory = info.uss/1024./1024
print(f"{hint} memory used: {memory} MB ")
def func():
show_memory_info("initial")
a = [i for i in range(1000000)]
b = [j for j in range(1000000)]
show_memory_info("after")
# 进行循环引用
a.append(b)
b.append(a)
func()
show_memory_info("finished")
运行结果:
解决循环引用
可以通过显式调用 gc.collection() 来解决循环引用造成的问题:
代码如下:
import gc
import os
import psutil
def show_memory_info(hint):
# 获取当前进程的进程号
pid = os.getpid()
# psutil 是一个获取系统信息的库
p = psutil.Process(pid)
info = p.memory_full_info()
memory = info.uss/1024./1024
print(f"{hint} memory used: {memory} MB ")
def func():
show_memory_info("initial")
a = [i for i in range(1000000)]
b = [j for j in range(1000000)]
show_memory_info("after")
# 进行循环引用
a.append(b)
b.append(a)
func()
# (2) 对于出现了循环引用的情形 可以显式调用 gc.collection() 来进行垃圾回收
gc.collect()
show_memory_info("finished")
运行结果:
引用显示工具
# 使用 objgraph 来观察循环引用 了解即可
# show_refs(),它可以生成清晰的引用关系图。
import objgraph
a = [1, 2, 3]
b = [4, 5, 6]
a.append(b)
b.append(a)
objgraph.show_refs([a])
import objgraph
a = [1, 2, 3]
b = [4, 5, 6]
a.append(b)
b.append(a)
objgraph.show_backrefs([a])
|
|