首页 > 系统相关 >python是如何进行内存管理的

python是如何进行内存管理的

时间:2024-10-19 23:18:19浏览次数:9  
标签:Python python 引用 回收 如何 对象 内存 垃圾

一、python内存管理

这个问题需要从三个方面来说:

相关书在python33点(0M

  • 1)对象的引用计数机制(四增五减)
  • 2)垃圾回收机制(手动自动,分代回收)
  • 3)内存池机制(大m小p)

1)对象的引用计数机制

要保持追踪内存中的对象,Python使用了引用计数这一简单的技术。sys.getrefcount(a)可以查看a对象的引用计数,但是比正常计数大1,因为调用函数的时候传入a,这会让a的引用计数+1

a)增加引用计数

对象被创建:x = 3.14
另外的别名被创建:y = x
对象被作为参数传递给函数(新的本地引用):foobar(x)
对象成为容器对象的一个元素:myList = [123, x, ‘xyz’]

b)减少引用计数

对象的一个别名被赋值给其他对象:x = 123
对象的别名被显式销毁:del y
一个本地引用离开了其作用范围。如fooc()函数结束时,func函数中的局部变量(全局变量不会)
对象被从一个窗口对象中移除:myList.remove(x)
窗口对象本身被销毁:del myList

c)引用计数例子,加深理解

id()获取对象的内存地址

在Python中,整数和短小的字符,Python都会缓存这些对象,以便重复使用。当我们创建多个等于1的引用时,实际上是让所有这些引用指向同一个对象

让我们来看看较长的字符串:

sys.getrefcount()来获取对象的引用计数:

2)垃圾回收机制

吃太多,总会变胖,Python也是这样。当Python中的对象越来越多,它们将占据越来越大的内存。不过你不用太担心Python的体形,它会在适当的时候“减肥”,启动垃圾回收(garbage collection),将没用的对象清除

从基本原理上,当Python的某个对象的引用计数降为0时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾了

比如某个新建对象,它被分配给某个引用,对象的引用计数变为1。如果引用被删除,对象的引用计数为0,那么该对象就可以被垃圾回收。比如下面的表

del a后,已经没有任何引用指向之前建立的[1, 2, 3]这个表。这个对象如果继续待在内存里,就成了不健康的脂肪。当垃圾回收启动时,Python扫描到这个引用计数为0的对象,就将它所占据的内存清空

然而,减肥是个昂贵而费力的事情。垃圾回收时,Python不能进行其它的任务。频繁的垃圾回收将大大降低Python的工作效率。如果内存中的对象不多,就没有必要总启动垃圾回收

所以,Python只会在特定条件下,自动启动垃圾回收。当Python运行时,会记录其中分配对象(object allocation)和取消分配对象(object deallocation)的次数。当两者的差值高于某个阈值时,垃圾回收才会启动

我们可以通过gc模块的get_threshold()方法,查看该阈值:

返回(700, 10, 10),后面的两个10是与分代回收相关的阈值,后面可以看到。700即是垃圾回收启动的阈值。可以通过gc中的set_threshold()方法重新设置。

我们也可以手动启动垃圾回收,即使用gc.collect()

分代回收:

Python同时采用了分代(generation)回收的策略。这一策略的基本假设是,存活时间越久的对象,越不可能在后面的程序中变成垃圾。

我们的程序往往会产生大量的对象,许多对象很快产生和消失,但也有一些对象长期被使用。出于信任和效率,对于这样一些“长寿”对象,我们相信它们的用处,所以减少在垃圾回收中扫描它们的频率

Python将所有的对象分为0,1,2三代。所有的新建对象都是0代对象。当某一代对象经历过垃圾回收,依然存活,那么它就被归入下一代对象。垃圾回收启动时,一定会扫描所有的0代对象

如果0代经过一定次数垃圾回收,那么就启动对0代和1代的扫描清理。当1代也经历了一定次数的垃圾回收后,那么会启动对0,1,2,即对所有对象进行扫描

这两个次数即上面get_threshold()返回的(700, 10, 10)返回的两个10。也就是说,每10次0代垃圾回收,会配合1次1代的垃圾回收;而每10次1代的垃圾回收,才会有1次的2代垃圾回收

同样可以用set_threshold()来调整,比如对2代对象进行更频繁的扫描

3)内存池机制

Python中有分为大内存和小内存:(256K为界限分大小内存)

1、大内存使用malloc进行分配

2、小内存使用内存池进行分配

python中的内存管理机制都有两套实现,一套是针对小对象,就是大小小于256K时,pymalloc会在内存池中申请内存空间;当大于256K时,则会直接执行系统的malloc的行为来申请内存空间

标签:Python,python,引用,回收,如何,对象,内存,垃圾
From: https://blog.csdn.net/dfhdfhhjil/article/details/143086229

相关文章

  • 使用 NVBit 进行内存访问跟踪指南
    使用NVBit进行内存访问跟踪指南NVBit(NVIDIABinaryInstrumentationTool)是NVIDIA提供的一款轻量级、灵活的GPU二进制插桩框架,可以帮助开发者在不修改源代码的情况下,跟踪CUDA程序的内存访问。具有以下特点:轻量级和高效:对应用程序的性能影响较小。灵活性:支持用户......
  • 企业it资产管理系统(Python+lw+系统源码 +调试)
    摘 要网络的广泛应用给生活带来了十分的便利。所以把企业it资产管理与现在网络相结合,利用Python技术建设企业it资产管理系统,实现企业it资产的信息化。则对于进一步提高企业it资产管理发展,丰富企业it资产管理经验能起到不少的促进作用。企业it资产管理系统能够通过互联网得......
  • NBA球员分析与可视化和信息管理系统(Python+Django+lw+系统源码 +调试)
    摘 要近年来,科技飞速发展,在经济全球化的背景之下,大数据将进一步提高社会综合发展的效率和速度,大数据技术也会涉及到各个领域,而爬虫实现网站数据可视化在网站数据可视化背景下有着无法忽视的作用。管理信息系统的开发是一个不断优化的过程,随着网络大数据时代的到来,管理信息......
  • 基于Python的电影分析推荐系统的设计与实现(源码+LW+调试文档)
    目录:程序功能截图:程序部分代码参考:数据库sql:程序技术介绍:后端springboot介绍:mysql介绍:程序论文:​选择我的理由:程序获取:......
  • Java的重载和主要内存区
    JAVA的重载​在Java中,重载(Overloading)是指在同一个类中可以定义多个同名的方法,但它们的参数列表必须不同。重载可以通过改变参数的数量、类型或者顺序来实现。重载提高了代码的可读性和灵活性。JAVA重载要满足的条件:在同一个类下:java的重载必须在同一个类之下方法名相同......
  • 【Java基础】物理内存&虚拟内存
    前言在Java程序运行过程中,操作系统为其分配了物理内存和虚拟内存。理解这两者的概念有助于明晰内存管理和性能优化。一、物理内存物理内存是指计算机的实际RAM(随机存取存储器)。Java进程在运行时需要向操作系统请求内存资源,操作系统通过分配物理内存来满足Java进程的内存......
  • Python基础入门
    目录1.简介2.安装与设置2.1检查是否已安装Python2.2使用Python解释器2.3使用代码编辑器3.Python基础语法3.1注释3.2变量和数据类型3.3输入输出3.4基本运算4.条件语句与循环4.1条件判断4.2循环while循环for循环break与continue5.函数与模块5.1......
  • 数据不裸奔:如何确保AI分析顾客数据时的隐私保护
    在这个信息爆炸的时代,数据已成为最宝贵的资源之一。人工智能(AI)技术的发展,使得我们能够从海量数据中提取有价值的信息,为商业决策提供支持。然而,随着AI在数据分析领域的广泛应用,顾客隐私保护问题也日益凸显。如何在利用AI分析顾客数据的同时,确保他们的隐私不被侵犯,成为了一个亟待......
  • Python+PyCharm安装教程,Python+Pycharm环境配置和使用指南,以及如何使用pycharm运行你
    Python+PyCharm安装教程,Python+Pycharm环境配置和使用指南,以及如何使用pycharm运行你的python代码(保姆级)一、Python下载与安装真实在Windows上安装过Python的小伙伴会发现在Windows上安装Python真的和安装普通软件一样简单,我们只需要在官网下载个安装包,然后猛击“下一步......
  • Python算法题常用函数记忆清单
    系统设计题&模拟题链接:https://leetcode.cn/problem-list/design/字符串操作splite按指定分隔符转成liststr_list=text.split() #默认按空格分割(函数写在后面,用.来调用)str_list=text.split(",") #按逗号分割 strip()去除两边的空格trimmed_text=text......