栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Python笔记,面向对象(12)内存管理机制

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python笔记,面向对象(12)内存管理机制

内存管理机制
  • 存储方面
  • 垃圾回收方面
    • 引用计数器
      • 概念
      • 查看引用计数
      • 举例
        • 引用计数的两个场景
        • 循环引用问题
    • 垃圾回收
      • 主要作用
      • 底层机制
        • 怎样找到“循环引用”?
        • 如歌提升查找“循环引用”的性能?
        • 查看以及修改机制配置参数
      • 垃圾回收时机
        • 自动回收
        • 手动回收

存储方面

1.在Python中万物接对象

  • 不存在基本数据类型
  • 0,1.2,True,False,“abc”这些全都是对象

2.所有对象中,都会在内存中开辟一块空间进行存储

  • 会根据不同的类型及其内容,开辟不同的空间大小进行存储
  • 返回该空间的地址给外界接受(称为"引用"),用于后续对这个对象的操作
    • 可通过id()函数获取内存地址(10进制)
    • 通过hex()函数可以查看对应的16进制地址
class Person:     
    pass          
                  
p = Person        
print(p)          
print(id(p))      
print(hex(id(p))) 

#结果

2495730068704
0x245151aace0
  • 3.对于整数和短小的字符,Python会进行缓存,不会创建对个相同对象
num1 = 2                   
num2 = 2                   
                           
print(id(num1), id(num2))  

#结果
1632086026576 1632086026576

4.容器对象,存储的其他对象,仅仅是其他对象的引用,并不是其他对象本身

垃圾回收方面 引用计数器 概念
  • 一个对象,会记录着自身被引用的个数
  • 每增加一个引用,这个对象的引用计数会自动+1
  • 每减少一个引用,这个对象的引用计数会自动-1
查看引用计数
  • import sys
  • sys.getrefcount: 注意会大一(调用这个函数,会被当做一个参数传递给这个函数)
import sys

class Person:
    pass



p1 = Person()

print(sys.getrefcount(p1))

p2 = p1

print(sys.getrefcount(p1))

del p2

print(sys.getrefcount(p1))

del p1


#结果
2
3
2
举例 引用计数的两个场景
  • 引用计数+1场景
    • 对象被创建:p1 = Person()
    • 对象被引用:p1 = p2
    • 对象被作为参数,传入到一个函数中
    • 对象作为一个元素,存储在容器中:i = [P1]
  • 引用计数-1场景
    • 对象的别名被显示销毁:del p1
    • 对象的别名被赋予新的对象:p1 = 123
    • 一个对象刚离开他的作用域:一个函数执行完毕时,内部的局部变量关联的对象,她的引用对象会再次被释放
    • 对象的容器被销毁,或从容器中删除对象
循环引用问题

内存泄露:一个对象在内存中无法使用,没有被释放的情况就是内存泄露

#objgraph.count()可以查看,垃圾回收器,跟踪的对象个数
import objgraph

class Person:
    pass
class Dog:
    pass

p = Person()
d = Dog()

print(objgraph.count("Person"))
print(objgraph.count("Dog"))

p.pet = d
d.master = p

#删除p,d之后,对应的对象是否被释放掉
del p
del d

print(objgraph.count("Person"))
print(objgraph.count("Dog"))

p.pet = d
d.master = p

del p
del d


#结果
1
1
1
垃圾回收 主要作用

从经历过"引用计数器机制"仍未被释放的对象中,找到"循环引用",干掉相关对象

底层机制 怎样找到“循环引用”?

如歌提升查找“循环引用”的性能?

查看以及修改机制配置参数
import gc

print(gc.get_threshold())   #查看
gc.set_threshold(200, 5, 5)   #更改


#结果
(700, 10, 10)  每查10次0代的,查一次1代的,依次类推
垃圾回收时机 自动回收

import gc

gc.disable()
print(gc.isenabled())

gc.enable()
print(gc.isenabled())

print(gc.get_threshold())
gc.set_threshold(1000, 5, 5)   #一般往大调,提升性能,垃圾回收耗时间

##
False
True
(700, 10, 10)

手动回收
import objgraph
import gc

#定义两个类
class Person:
    pass

class Dog:
    pass

#根据这两个类,创建出两个实例对象
p = Person()
d = Dog()

#让两个实例对象之间互相引用,造成循环引用
p.pet = d
d.master = p

#尝试删除可达到引用之后,测试真实对象是否有被回收
del p
del d

#通过"引用计数机制”无法回收,需要借助“垃圾回收机制”
gc.collect()  #手动触发回收,不管垃圾回收机制是否开启,括号内写几就是回收哪一代

print(objgraph.count("Person"))
print(objgraph.count("Dog"))

#
0
0
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1031223.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号