扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
垃圾回收机制: 简称GC,是Python解释器自带的一种机制,专门用来回收不可用的变量值所占用的内存空间,我们通过垃圾回收机制来清除在程序运行过程中申请的但是没有用到的内存空间,避免了内存溢出导致程序崩溃,通过垃圾回收机制帮助程序员解决繁杂的内存管理。
垃圾回收机制的原理: Python的垃圾回收机制主要通过使用"引用计数"来跟踪和回收垃圾,并且在引用计数的基础上,通过"标记-清除"来解决容器对象可能产生的循环引起的问题,并且通过"分代回收"以空间换取时间的方式来进一步提高垃圾回收的效率。
列表在内存中存储的形式大致如下:
此时L[1]属于间接引用,假如我们实现如下代码,可以看到直接引用和间接引用不同的形式
x = 10
List=['a',x]
print("这是直接引用:",x) #直接引用
print("这是间接引用:",List[1]) #此为间接引用
所以List作为列表,是一个容器,相当于一个目录,通过索引来间接引用到真实的数值。
通过以下代码,我们可以理解下间接索引的效果:
x=123
List=['a','b',x]
print("List[2]=",List[2])
x=321
print("List[2]=",List[2])
说明在列表中传入的x,实际上传入的是x的值的内存地址,传入后x这个值的引用计数加一。
引用计数详解如下图中Python代码中值culin被捆绑给了两个变量,所以它的引用计数就是2,换言之,如果引用计数为零,那么它就是垃圾。
name="culin" #culin的引用计数为1
sex=name #culin的引用计数为2
如何减少引用计数
name="culin"
sex=name
del name #解除变量名name与值"culin"的绑定,此时culin的引用计数减1
print(sex)
sex="male" #变量sex先与"culin"解除绑定,然后再与"male"绑定,此时culin的引用计数减1
循环引用带来的内存泄露问题
l1 = [111, ] # 此时l1引用计数为1
l2 = [222, ] # 此时l2引用计数为1
print(id(l1), id(l2))
l1.append(l2) # 此时l2引用计数为2
l2.append(l1) # 此时l1引用计数为1
del l1
print(id(l2[1])) # 可以看到还是可以访问到l1原来所指的内容
del l2 # 此时虽然我们del l1 和 l2 但是 l1 和 l2 在内存中都还有1个计数
# 此时垃圾回收机制不起作用,但是l1和l2不再会用到。造成内存泄露
标记清除机制为了解决上述循环引用带来的内存泄露问题,python中引入了标记清除来作为解决方案。在Python整个内存不够用的时候,会暂时停止运行,然后扫描栈区,然后将栈区存在的变量都标记为存活,否则标记为未存活,然后清除堆区的垃圾内容。当栈区内不存在l1和l2,只剩下堆区的l1和l2相互引用,于是l1和l2被标记为未存活,清理两者,解决了上述存在的循环引用带来的内存泄露问题。
分代回收机制因为基于引用计数的垃圾回收机制,每次回收内存的时候都要遍历扫描,其实这是非常消耗时间的。所以分代回收机制采用了**类似局部性原理的思想,**使用"空间换时间"的策略来解决这个问题。
分代回收核心思想: 在历经多次扫描的情况下,都没有被回收的变量,垃圾回收机制就会认为,该变量是常用变量,垃圾回收机制对其扫描的频率会降低。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流