• 探索 Python 的动态类型系统:变量引用、不可变性及高效内存管理与垃圾回收机制的深入分析


    Python作为一种流行的高级编程语言,以其代码的易读性和简洁性著称。尤其是它的动态类型系统和自动内存管理,使得开发者可以更加专注于实现功能而非处理底层细节。下面就来讲讲,今天面试被问到了。


    1. 动态类型及其内存管理解析

    Python 作为一种动态类型的编程语言,允许开发者在声明变量时不需要指定数据类型。此外,Python 中的一切皆为对象,变量则是对这些对象的引用。

    1.1 变量与对象的引用关系

    同一个对象可以被多个变量引用

    # 创建变量 x 并赋值为 10
    x = 10
    print("变量 x 的类型:", type(x)) # 变量 x 的类型: 
    
    # 创建变量 y,将其引用设置为变量 x 的引用
    y = x
    print("x 引用的对象地址:", hex(id(x))) # 0x7ff0ab01a3d0
    print("y 引用的对象地址:", hex(id(y)))# 0x7ff0ab01a3d0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    xy 都引用了同一个整数对象 10

    补充:hex() 用于将一个整数转换成对应的十六进制字符串

    1.2 对象的不可变性和内存地址的变化

    修改 x 的值,并观察 xy 的引用是否发生变化:

    # 修改变量 x 的值
    x += 1
    print("修改后 x 的地址:", hex(id(x))) # 修改后 x 的地址: 0x7ff0ab01a3f0
    
    • 1
    • 2
    • 3

    当对 x 进行加 1 操作时,由于整数是不可变类型,x 指向了一个新的整数对象 11,而原有的整数对象 10 保持不变。

    2. 垃圾回收与内存优化策略

    Python的动态类型允许程序在运行时创建、修改和销毁对象,这种灵活性虽然提供了极大的便利,但也带来了对内存管理机制的依赖。

    2.1 动态内存分配的基础

    在 Python 中,变量在创建时不需要声明数据类型,因此,Python 需要在运行时动态地管理内存。这主要通过堆内存来实现,其中对象的创建、修改和销毁都在堆内存中进行。

    def bar(a):
        a = a - 1
        return a
    
    def foo(a):
        a = a * a
        b = bar(a)
        return b
    
    def main():
        x = 2
        y = foo(x)
    
    if __name__ == "__main__":
        main()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    main 函数被调用时,局部变量 xy 被创建并存储在调用栈上,而通过 foobar 函数创建的对象则存储在堆上。当 foobar 函数执行完毕后,它们可能会在堆上留下未被回收的对象,这就是动态内存管理中需要解决的问题。

    运行时:

    在这里插入图片描述

    运行结束:

    在这里插入图片描述

    2.2 Python 的垃圾回收

    Python 通过一个内置的垃圾收集器来管理内存,它主要使用引用计数和标记-清除算法来追踪和清除不再使用的对象。

    引用计数: Python 对每个对象维护一个引用计数,每当对象的引用数变为零时,该对象就会被垃圾收集器回收。

    import sys
    
    class Color:
        def __init__(self, r, g, b):
            self.red = r
            self.green = g
            self.blue = b
    
    clr = Color(255, 0, 0)
    print("clr 对象的引用计数:", sys.getrefcount(clr) - 1)  
    # 减1是因为getrefcount在调用时也会增加一次引用计数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    循环引用问题: 引用计数方法不能处理对象间的循环引用,例如两个对象互相引用。


    推荐: python 错误记录
    参考:Python Memory Management

  • 相关阅读:
    HBase学习笔记(3)—— HBase整合Phoenix
    (二十)数据结构-查找的基本概念
    机器学习写代码时遇到的问题(23.11.9)
    初识java
    基于Web的个人网页响应式页面设计与实现 HTML+CSS+JavaScript(web前端网页制作课作业)
    Docsify 顶部的导航是如何配置
    C++问题:在共享库 clang 中创建入口点时未定义的引用
    CVPR2022 | 简单高效的语义分割体系结构
    shell 查看当前日期时间
    No module ‘xformers‘. Proceeding without it.
  • 原文地址:https://blog.csdn.net/lph159/article/details/138198195