求知讲堂python+人工智能day12

pyth的垃圾回收机制

GC(垃圾回收)负责的主要任务

  1. 为新生成的对象分配内存
  2. 识别那些垃圾对象
  3. 从垃圾对象那回收内存

引用计数机制

  • Garbage collection(GC)模块的使用(垃圾回收)
  • 现在的高级语言如java,c#等,都采用了垃圾收集机制,而不再是c,c++里用户自己管理维护内存的方式。自己管理内存极其自由,可以任意申请内存,但如同一把双刃剑,为大量内存泄露,悬空指针等bug埋下隐患。
  • 对于一个字符串、列表、类甚至数值都是对象,且定位简单易用的语言,自然不会让用户去处理如何分配回收内存的问题。
  • python里也同java一样采用了垃圾收集机制,不过不一样的是: python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略

在这里插入图片描述

import sys
# 创建时候1次,查看时候一次
a=[]
print('a被引用的次数是:{}'.format(sys.getrefcount(a)))

# 上面查看结束后会自动释放,所以创建1次,赋值1次,查看1次
b=a
print('a被引用的次数是:{}'.format(sys.getrefcount(a)))
print('b被引用的次数是:{}'.format(sys.getrefcount(b)))

# 被间接引用也算引用
c=b
d=c
print('a被引用的次数是:{}'.format(sys.getrefcount(a)))

在这里插入图片描述
引用机制的优点:

  • 简单
  • 实时性:一旦没有引用,内存就直接释放了。不用像其他机制需要等到特定时机。实时性还带来一个好处:处理回收内存的时间分摊到了平时

引用机制的缺点:

  • 维护引用计数会消耗资源
  • 循环引用就不适用了
list1 = []
list2 = []
list1.append(list2)
list2.append(list1)

list1与list2相互引用,如果不存在其他对象对它们的引用,list1与list2的引用计数也仍然为1,所占用的内存永远无法被回收,这将是致命的。对于如今的强大硬件,缺点1尚可接受,但是循环引用导致内存泄露,注定python还将引入新的回收机制。(标记清除和分代收集)

Python中的循环数据结构及引用计数

标记-清除机制
import psutil
import os

def showMemSize(tag):
    pid=os.getpid() # 得到进程id
    p=psutil.Process(pid) # 进程对象
    info=p.memory_full_info() # 当前占用的内存信息
    memory=info.uss/1024/1024 # 将字节格式转换为兆
    print('{} memory used:{} MB'.format(tag,memory))
    pass

# 验证循环引用的情况
def func():
    showMemSize('初始化')
    a=[i for i in range(10000000)]
    b=[i for i in range(10000000)]
    a.append(b)
    b.append(a)
    showMemSize('创建列表对象 a b 之后')
    pass

func()
showMemSize('完成时候的')

在这里插入图片描述

import psutil
import os
import sys

def showMemSize(tag):
    pid=os.getpid() # 得到进程id
    p=psutil.Process(pid) # 进程对象
    info=p.memory_full_info() # 当前占用的内存信息
    memory=info.uss/1024/1024 # 将字节格式转换为兆
    print('{} memory used:{} MB'.format(tag,memory))
    pass

# 验证循环引用的情况
def func():
    showMemSize('初始化')
    a=[i for i in range(10000000)]
    b=[i for i in range(10000000)]
    a.append(b)
    b.append(a)
    showMemSize('创建列表对象 a b 之后')
    print(sys.getrefcount(a))
    print(sys.getrefcount(b))
    del a
    del b
    pass

func()
showMemSize('完成时候的')

在这里插入图片描述

import psutil
import os
import gc  # 导入垃圾回收机制

def showMemSize(tag):
    pid=os.getpid() # 得到进程id
    p=psutil.Process(pid) # 进程对象
    info=p.memory_full_info() # 当前占用的内存信息
    memory=info.uss/1024/1024 # 将字节格式转换为兆
    print('{} memory used:{} MB'.format(tag,memory))
    pass

# 验证循环引用的情况
def func():
    showMemSize('初始化')
    a=[i for i in range(10000000)]
    b=[i for i in range(10000000)]
    a.append(b)
    b.append(a)
    showMemSize('创建列表对象 a b 之后')
    pass

func()
gc.collect()  # 利用gc手动释放内存
showMemSize('完成时候的')

在这里插入图片描述

Python中gc模块

有三种情况会触发垃圾回收:(默认是开启垃圾回收的)

  1. 当gc模块的计数器达到阀值的时候,自动回收垃圾
  2. 调用gc.collect(),手动回收垃圾
  3. 程序退出的时候,python解释器来回收垃圾

在这里插入图片描述
在这里插入图片描述

python内存优化

小整数与大整数对象池

Python为了优化速度,使用了小整数对象池, 避免为整数频繁申请和销毁内存空间。 Python 对小整数的定义是 [-5, 256] 这些整数对象是提前建立好的,不会被垃圾回收。

在这里插入图片描述

python命令行参数

命令行参数-sys模块(1)

在使用python开发脚本,作为一个运维工具,或者其他工具需要接受用户参数运行时,这里就可以用到命令行传参的方式,可以给使用者提供一个比较友好的交互体验。

1、新建一个test.py

# Python可以 sys模块中的 sys.argv 来获取命令行参数
import sys
print('参数个数为:', len(sys.argv), '个参数。')
print('参数列表:', str(sys.argv))

在这里插入图片描述
2、一般我们不直接执行,而是在路径下,用命令行参数执行
在这里插入图片描述

命令行参数-sys模块(2)

argv 返回命令行参数是一个列表,第一个元素就是 py文件的文件名。如果只想获取参数不需要获取文件名,sys.argv也支持python字符串中的切片 修改代码如下:

# Python可以 sys模块中的 sys.argv 来获取命令行参数
import sys
print('参数个数为:', len(sys.argv), '个参数。')
print('参数列表:', str(sys.argv[1:]))  # 切片形式从第二个开始提取数据

在这里插入图片描述
第一个是文件名,所以可以切片形式提取。
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值