← 返回 Day 53 正文

Day 53 · 图解

Day 053 — 内存管理与垃圾回收图解

1. Python 内存管理架构

graph TD A[Python 应用程序] --> B[内存分配器] B --> C[pymalloc] B --> D[操作系统] C --> E[对象分配] C --> F[内存池] E --> G[引用计数] E --> H[垃圾回收器] G --> I[自动回收] H --> J[标记-清除] H --> K[分代回收]
graph TD
    A[Python 应用程序] --> B[内存分配器]
    B --> C[pymalloc]
    B --> D[操作系统]

    C --> E[对象分配]
    C --> F[内存池]

    E --> G[引用计数]
    E --> H[垃圾回收器]

    G --> I[自动回收]
    H --> J[标记-清除]
    H --> K[分代回收]

2. 引用计数机制

sequenceDiagram participant Var as 变量 participant Obj as 对象 Var->>Obj: 创建对象 (refcount=1) Var->>Obj: 赋值给另一个变量 (refcount=2) Var->>Obj: 放入列表 (refcount=3) Note over Obj: 对象仍然存活 Var->>Obj: del 变量 (refcount=2) Var->>Obj: 从列表移除 (refcount=1) Var->>Obj: del 最后一个引用 (refcount=0) Note over Obj: 对象被立即回收
sequenceDiagram
    participant Var as 变量
    participant Obj as 对象

    Var->>Obj: 创建对象 (refcount=1)
    Var->>Obj: 赋值给另一个变量 (refcount=2)
    Var->>Obj: 放入列表 (refcount=3)

    Note over Obj: 对象仍然存活

    Var->>Obj: del 变量 (refcount=2)
    Var->>Obj: 从列表移除 (refcount=1)
    Var->>Obj: del 最后一个引用 (refcount=0)

    Note over Obj: 对象被立即回收

3. 循环引用问题

graph LR A[对象A] -->|强引用| B[对象B] B -->|强引用| A style A fill:#ff6b6b,color:#fff style B fill:#ff6b6b,color:#fff
graph LR
    A[对象A] -->|强引用| B[对象B]
    B -->|强引用| A

    style A fill:#ff6b6b,color:#fff
    style B fill:#ff6b6b,color:#fff

4. 分代回收原理

graph TD subgraph 第 0 代 A0[新对象] --> B0[存活对象] end subgraph 第 1 代 A1[从 0 代存活] --> B1[存活对象] end subgraph 第 2 代 A2[从 1 代存活] --> B2[长期存活] end B0 -->|存活| A1 B1 -->|存活| A2
graph TD
    subgraph 第 0 代
        A0[新对象] --> B0[存活对象]
    end

    subgraph 第 1 代
        A1[从 0 代存活] --> B1[存活对象]
    end

    subgraph 第 2 代
        A2[从 1 代存活] --> B2[长期存活]
    end

    B0 -->|存活| A1
    B1 -->|存活| A2

5. 标记-清除算法

graph TD A[开始 GC] --> B[标记阶段] B --> C[从根对象遍历] C --> D[标记可达对象] D --> E[清除阶段] E --> F[回收未标记对象] E --> G[保留标记对象]
graph TD
    A[开始 GC] --> B[标记阶段]
    B --> C[从根对象遍历]
    C --> D[标记可达对象]
    D --> E[清除阶段]
    E --> F[回收未标记对象]
    E --> G[保留标记对象]

6. gc 模块 API

graph TD subgraph gc 模块 A[gc.collect] --> B[手动触发回收] C[gc.get_objects] --> D[获取所有对象] E[gc.get_referrers] --> F[获取引用者] G[gc.get_referents] --> H[获取被引用对象] I[gc.get_threshold] --> J[获取回收阈值] K[gc.get_count] --> L[获取各代对象数] end
graph TD
    subgraph gc 模块
        A[gc.collect] --> B[手动触发回收]
        C[gc.get_objects] --> D[获取所有对象]
        E[gc.get_referrers] --> F[获取引用者]
        G[gc.get_referents] --> H[获取被引用对象]
        I[gc.get_threshold] --> J[获取回收阈值]
        K[gc.get_count] --> L[获取各代对象数]
    end

7. 内存泄漏检测流程

graph TD A[开始检测] --> B[获取内存快照] B --> C[执行操作] C --> D[再次获取快照] D --> E[对比快照] E --> F{内存增长?} F -->|是| G[可能存在泄漏] F -->|否| H[内存正常] G --> I[使用 gc.get_referrers 追踪] I --> J[找出引用链] J --> K[修复泄漏]
graph TD
    A[开始检测] --> B[获取内存快照]
    B --> C[执行操作]
    C --> D[再次获取快照]
    D --> E[对比快照]
    E --> F{内存增长?}
    F -->|是| G[可能存在泄漏]
    F -->|否| H[内存正常]

    G --> I[使用 gc.get_referrers 追踪]
    I --> J[找出引用链]
    J --> K[修复泄漏]

8. 内存优化策略

graph TD A[内存优化] --> B{对象类型?} B -->|小对象| C[使用 __slots__] B -->|大数据| D[使用生成器] B -->|字符串| E[使用 sys.intern] B -->|循环引用| F[使用 weakref] C --> G[减少内存开销] D --> H[避免一次性加载] E --> I[复用字符串对象] F --> J[避免内存泄漏]
graph TD
    A[内存优化] --> B{对象类型?}

    B -->|小对象| C[使用 __slots__]
    B -->|大数据| D[使用生成器]
    B -->|字符串| E[使用 sys.intern]
    B -->|循环引用| F[使用 weakref]

    C --> G[减少内存开销]
    D --> H[避免一次性加载]
    E --> I[复用字符串对象]
    F --> J[避免内存泄漏]

9. 内存使用可视化

内存使用示意图:
┌─────────────────────────────────────────────────────────┐
│                                                         │
│  ┌─────────────────────────────────────────────────┐   │
│  │ 对象堆                                           │   │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐           │   │
│  │  │ 对象 1   │ │ 对象 2   │ │ 对象 3   │  ...     │   │
│  │  └─────────┘ └─────────┘ └─────────┘           │   │
│  │                                                 │   │
│  │  第 0 代: 700 个对象                             │   │
│  │  第 1 代: 10 个对象                              │   │
│  │  第 2 代: 10 个对象                              │   │
│  └─────────────────────────────────────────────────┘   │
│                                                         │
│  ┌─────────────────────────────────────────────────┐   │
│  │ gc.garbage                                       │   │
│  │  ┌─────────┐ ┌─────────┐                        │   │
│  │  │ 无法回收 │ │ 无法回收 │  ...                    │   │
│  │  └─────────┘ └─────────┘                        │   │
│  └─────────────────────────────────────────────────┘   │
│                                                         │
└─────────────────────────────────────────────────────────┘