目录

python的内存管理

一、引用计数

1.1 python是一种动态类型, 所以需要引用计数

1.2 引用计数

1.3 引用计数无法解决 循环引用

二、垃圾回收

2.1 垃圾回收,为了解决引用计数的弊端

2.2 垃圾回收,产生的效率问题

2.3 什么时候垃圾回收

2.4 垃圾回收是怎么回收

2.4.1 怎么找到垃圾 --> 分代回收

2.4.2 怎么清除垃圾 ---> 标记清除, 清除循环引用的垃圾

2.4.3 内存泄露

2.4.4 内存溢出

三、内存池机制

3.1 小整数池 [-5,256]之间

3.2 字符串驻留区(对于多个字符,含有特殊字符,是不放在驻留区的;对于单个字符,都放在驻留区)


python的内存管理

引用计数为主,分代回收和清除标记为辅的垃圾回收方式,进行内存回收管理

还引用了小整型缓冲池以及常用字符串驻留区的方式进行内存分配管理

一、引用计数

1.1 python是一种动态类型, 所以需要引用计数

动态类型: 不使用显示数据类型来声明变量,且确定一个变量的类型 是在第一次给它赋值的时候确认的

1.2 引用计数

引用计数: 统计了有哪些变量引用 指向了当前对象当有新的引用指向变量,引用计数+1当有无效的引用发生的时候,引用计数-1当对象的引用计数为0的时候,销毁对象

1.3 引用计数无法解决 循环引用

引用计数可以解决大部分内存释放的问题,但是无法解决循环引用问题
​
删除x,y 引用,引用计数都减1, 但是引用计数并没有归0,
在内存中就不能被释放,程序又不能访问这片空间,造成内存泄露。
>>> from sys import getrefcount
​
>>> x = [1, 2]
>>> y = [3, 4]
>>> x.append(y)
>>> x
[1, 2, [3, 4]]
>>> y.append(x)
>>> y
[3, 4, [1, 2, [...]]]
>>> x
[1, 2, [3, 4, [...]]]
>>> del x
>>> del y
>>> x
Traceback (most recent call last):File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> y

二、垃圾回收

2.1 垃圾回收,为了解决引用计数的弊端

垃圾回收的作用(gc机制): garbage collection1. 找到内存中无用的垃圾资源2. 清除这些垃圾并把内存让出来给其他对象使用

2.2 垃圾回收,产生的效率问题

效率问题:垃圾回收,python不能进行其他的任务。频繁的垃圾回收将大大降低python的工作效率。

2.3 什么时候垃圾回收

什么时候垃圾回收:1. 手动调用gc.collect()2. GC达到阀值时python在运行时, 记录其中分配对象和取消分配对象的次数,当两者的差值高于某个阀值时,垃圾回收才会启动>>> gc.get_threshold()  # threshold 门限,阀限(700, 10, 10) 700这个阀值  3. 程序退出时
>>> import gc
>>> gc.get_threshold()  # threshold 门限,阀限
(700, 10, 10)
>>> gc.collect()
57
>>> gc.collect()
0
>>> 

2.4 垃圾回收是怎么回收

垃圾回收:1. 找到垃圾2. 回收垃圾    

2.4.1 怎么找到垃圾 --> 分代回收

 每一次只会检查新建对象
新建对象  ---> 0代成员 ---> 每一次垃圾回收的时候,都会被检查
>>> gc.get_threshold()  # threshold 门限,阀限
(700, 10, 10)
当0代成员,经历10次垃圾回收,依然存活 -----> 1代成员1 代成员有什么特权: 0代成员扫描10次,才会扫描一次 1代成员 1代成员扫描10次,依然存活 ----> 2代成员1代扫描10,才会扫描 2代成员最多只有 3代(0代,1代,2代)

2.4.2 怎么清除垃圾 ---> 标记清除, 清除循环引用的垃圾

采用分代回收,来扫描指定的对象,当检测到时垃圾的时候(标记对象),然后再清除垃圾(垃圾回收)。主要用于解决循环引用。1. 标记: 活动(有被引用),非活动(可被删除)2. 清除: 清除所有非活动的对象

2.4.3 内存泄露

什么是内存泄露:(占着茅坑不拉屎)有一部分内存无法被回收释放,进程又无法访问

2.4.4 内存溢出

内存溢出(out of memory):内存不够用,程序需要的内存大于系统空间的内存

三、内存池机制

>>> from sys import getrefcount
>>> a = 1
>>> b =2
>>> getrefcount(a)
799
>>> getrefocunt(b)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
NameError: name 'getrefocunt' is not defined
>>> getrefcount(b)  ----> 这些为什么有这么多的引用呢?
99
>>> c = 200
>>> getrefcount(c)
3
>>> d = 500    ----> python 中分别创建两个500对象
>>> f = 500
>>> getrefcount(d)
2
>>> getrefcount(f)
2
>>> >>> g = 1
>>> getrefcount(g)
800
>>> h = 1
>>> getrefcount(h)
805
>>> id(g)
140339374065568
>>> id(h)
140339374065568
>>> id(f)
140339374748784
>>> id(d)
140339374748464
>>>
==============
以上情形的出现,因为python有个内存池机制。小整数池(-5 ~ 256 ),已经全部创建好了

3.1 小整数池 [-5,256]之间

浮点型的没有
>>> a = 1.1
>>> b = 1.1
>>> getrefcount(a)
2
>>> getrefcount(b)
2

3.2 字符串驻留区(对于多个字符,含有特殊字符,是不放在驻留区的;对于单个字符,都放在驻留区)

当字符串中含有多个字符时,不是有特殊字符。有特殊字符,就不保留在驻留区;无特殊字符,就保留在驻留区驻留区 相当于 缓存一样,创建一个字符串。先去驻留区查看,是否有一样的,若有一样的,就直接引用。没有一样的,才新建对象
单个字符的案例
==============
>>> str1 = "中"
>>> str2 = "中"
>>> id(str1)
140339374898512
>>> id(str2)
140339374898752
>>>
=========
多个字符案例
===============
含有特殊字符 ----> 不放在驻留区
=============
>>> str1 = "abc'"
>>> str2 = "abc'"
>>> id(str1)
140339374939416
>>> id(str2)
140339374939472
==========================
不含有特殊字符  ----> 就放在驻留区
=====================
>>> str2 = "abc"
>>> str1 = "abc"
>>> id(str2)
140339375551632
>>> id(str1)
140339375551632
>>> 
驻留区有边界
================
>>> str1 = "a" * 20
>>> str2 = "a" * 20
>>> str1 is str2
True
>>> str2 = "a" * 21
>>> str1 = "a" * 21
>>> str1 is str2
False
>>>
========================

一篇搞懂python的内存管理相关推荐

  1. python文件打开模式rb表示只读模式打开文件_一篇搞懂python文件读写操作(r/r+/rb/w/w+/wb/a/a+/ab)...

    关于文件操作的几种常用方式,网上已有很多解说,内容很丰富,但也因此有些杂乱复杂.今天,我就以我个人的学习经验写一篇详细又易懂的总结文章,希望大家看完之后会有所收获. 一.各模式逐个分解 'r':只读. ...

  2. python中级程序员是什么水准_程序员进阶:一篇搞懂Python中级应用

    异常处理:try-except 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行.一般情况下,在Python无法正常处理程序时就会发生一个异常. 异常是Python对象,表示一个错 ...

  3. 一篇搞懂Python中的随机数

    在 python 中生成随机样本的所有你需要的示例列表 长按关注<Python学研大本营>,加入读者群,分享更多精彩 扫码关注<Python学研大本营>,加入读者群,分享更多精 ...

  4. 一篇搞懂python文件读写操作(r/r+/rb/w/w+/wb/a/a+/ab)

     关于文件操作的几种常用方式,网上已有很多解说,内容很丰富,但也因此有些杂乱复杂.今天,我就以我个人的学习经验写一篇详细又易懂的总结文章,希望大家看完之后会有所收获. 一.核心功能 'r':只读.该文 ...

  5. python中w和wb区别_一篇搞懂python文件讀寫操作(r/r+/rb/w/w+/wb/a/a+/ab)

    關於文件操作的幾種常用方式,網上已有很多解說,內容很豐富,但也因此有些雜亂復雜.今天,我就以我個人的學習經驗寫一篇詳細又易懂的總結文章,希望大家看完之后會有所收獲. 一.各模式逐個分解 'r':只讀. ...

  6. python中w和wb区别_一篇搞懂python文件读写操作(r/r+/rb/w/w+/wb/a/a+/ab)

    关于文件操作的几种常用方式,网上已有很多解说,内容很丰富,但也因此有些杂乱复杂.今天,我就以我个人的学习经验写一篇详细又易懂的总结文章,希望大家看完之后会有所收获. 一.各模式逐个分解 'r':只读. ...

  7. python 类-Python入门--一篇搞懂什么是类

    原标题:Python入门--一篇搞懂什么是类 写一篇Python类的入门文章,在高级编程语言中,明白类的概念和懂得如何运用是必不可少的.文章有点长,3000多字. Python是面向对象的高级编程语言 ...

  8. python协程详解_彻底搞懂python协程-第一篇(关键词1-4)

    任何复杂的概念或系统都不是凭空出现的,我们完全可以找到它的演化历程,寻根究底终会发现,其都是在一系列并不那么复杂的简单组件上发展演化而来! by 落花僧 本文通过一系列关键概念,逐步递进理解协程. 0 ...

  9. python语言语句快的标记是什么_一文搞懂Python程序语句

    原标题:一文搞懂Python程序语句 程序流 Python 程序中常用的基本数据类型,包括: 内置的数值数据类型 Tuple 容器类型 String 容器类型 List 容器类型 自然的顺序是从页面或 ...

最新文章

  1. 【鸿蒙 HarmonyOS】UI 布局 ( 帧布局 StackLayout )
  2. NYOJ 460 项链
  3. 关于完美拖拽的问题三
  4. js动态添加meta标签
  5. 高压电是以交流,还是直流方式输送?
  6. 怎么在linux的cmd中运行c项目,如何在cmd窗口编译运行c语言程序?
  7. 常用宏定义 - 系统相关
  8. 博士生Science发文:很庆幸导师要求每周交工作进展汇报!
  9. python计算数组元素个数_python简单获取数组元素个数的方法
  10. 10米精度NPP净初级生产力数据/NDVI数据/植被类型数据/土地利用数据/降雨气温分布数据/太阳辐射分布数据
  11. 开源旅游网站系统排名
  12. 1. 物理内存初始化-linux4.0
  13. 全民健身时代到来,运动类APP如何秀出肌肉?
  14. 欧可林Oclean X Pro旗舰版:大学生的私人口腔医生
  15. max31865模块 PT100测温 PT1000测温 接线说明要点说明 使用说明 程序 单片机
  16. QStackWidget使用 踩坑
  17. idea中vue文件 游览器图标_vue项目中icon图标的完美引入
  18. 网络之路--【第四章】——IP编址之IP详解
  19. linux命令查看iotop,Linux系统IO分析工具之iotop参数详解(查看IO占用)
  20. 第三届北京·顺义张镇灶王文化节即将开幕

热门文章

  1. 乐视乐2怎么恢复误删照片
  2. Future模式详解
  3. 关系型数据库MySql与非关系型数据库NoSql
  4. [博弈论] 三个枪手
  5. lampApache配置
  6. 枪火重生灵界狂潮攻略(三)兔子流派
  7. 快手小店赠品有什么规范?赠品管理规范
  8. 仿QQ空间、微信朋友圈点击评论弹出输入框
  9. 原生js获取html元素高度,js获取页面及个元素高度、宽度的代码
  10. Autodesk推出最新SketchBook Pro 7