You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Pandas在Ubuntu上的内存占用远高于macOS?

Pandas/Numpy跨平台内存泄漏问题排查与解决

环境配置

  • 操作系统:Linux Ubuntu 22.04、macOS Monterey 12.2.1
  • Python版本:3.10
  • 依赖库:Pandas 1.5.2、Numpy 1.23.5、Psutil 5.9.5(两端版本完全一致)

问题现象

在macOS开发的Python代码部署到Ubuntu服务器后,内存占用差异显著:Ubuntu端内存会快速耗尽并导致进程被终止。通过测试代码复现,确认Pandas相关操作存在内存泄漏,使用Memray分析定位到泄漏点在'dot at <__array_function__internals>'行,但无法进一步排查。

复现测试代码

import pandas as pd
import numpy as np
import psutil
import sys
import ctypes

# 设置循环次数
n                   = 100000
memory_check        = 0
memory_check_prev   = 0

# 存储相关系数的列表
correlation_values = []

# 创建随机数据的DataFrame
df = pd.DataFrame(np.random.rand(3600, 2), columns=['Column1', 'Column2'])

# 循环执行相关计算
for _ in range(n):
    ### 相关系数计算
    correlation     = df['Column1'].corr(df['Column2'])
    ### 其他可测试操作(注释状态)
    # df['returns']   = df['Column1'].pct_change()
    # df2             = df.loc[200:500]
    # df2             = df.loc[str(200):str(500)]

    # 调用malloc_trim回收内存
    if sys.platform.startswith('linux'):
        malloc_lib = ctypes.CDLL('/usr/lib/x86_64-linux-gnu/libc.so.6')
    else:
        malloc_lib = ctypes.CDLL('/Users/koen/libcustommalloc.dylib')
    malloc_lib.malloc_trim.argtypes = [ctypes.c_size_t]
    malloc_lib.malloc_trim.restype  = None
    malloc_lib.malloc_trim(0)

    # 检查内存变化
    memory_check    = psutil.Process().memory_info().rss / 1000000000
    if memory_check != memory_check_prev:
        print('New total memory load: ' + str(memory_check))
        memory_check_prev = memory_check

Malloc_trim 环境准备

  • Linux端:直接使用系统libc库路径/usr/lib/x86_64-linux-gnu/libc.so.6
  • macOS端:需编译自定义dylib文件,C代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <malloc/malloc.h>

void malloc_trim(size_t pad) {
    malloc_zone_t *zone = malloc_default_zone();
    malloc_zone_pressure_relief(zone, pad);
}

编译命令:

gcc -shared -o libcustommalloc.dylib -fPIC custommalloc.c

编译完成后修改Python代码中的对应路径。

解决方案与排查方向

  1. 升级依赖库版本
    Pandas 1.5.2和Numpy 1.23.5存在已知的底层内存管理问题,建议升级到:
  • Pandas 1.5.3+ 或 2.x 系列
  • Numpy 1.24.x+
    这些版本修复了多个内存泄漏相关的bug,尤其是涉及到dot运算和DataFrame操作的场景。
  1. 替换Pandas方法为原生Numpy实现
    Pandas的corr方法封装了Numpy的计算逻辑,直接使用Numpy的np.corrcoef可以减少封装层的内存开销,避免潜在的泄漏:
# 替换原correlation计算行
correlation = np.corrcoef(df['Column1'].values, df['Column2'].values)[0, 1]
  1. 优化内存回收策略
  • 减少malloc_trim的调用频率:频繁调用会影响性能,可改为每N次循环调用一次(如每100次)
  • 主动触发Python垃圾回收:结合gc模块在循环间隙回收内存
import gc
# 在循环内添加
if _ % 100 == 0:
    gc.collect()
    if sys.platform.startswith('linux'):
        malloc_lib = ctypes.CDLL('/usr/lib/x86_64-linux-gnu/libc.so.6')
        malloc_lib.malloc_trim(0)
  1. 排查Numpy后端问题
    Ubuntu默认的OpenBLAS后端可能存在内存泄漏,可尝试:
  • 切换到MKL后端(通过conda install numpy mkl安装)
  • 编译Numpy时启用内存分配优化选项
  1. 深入内存分析
  • 使用Python内置的tracemalloc追踪Python层面的内存分配:
import tracemalloc
tracemalloc.start()

# 执行测试代码后获取快照
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
for stat in top_stats[:10]:
    print(stat)
  • 使用Linux的valgrind工具排查C层面泄漏(注意:会大幅降低程序运行速度):
valgrind --leak-check=full python your_script.py

内容的提问来源于stack exchange,提问作者Koen Smits

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 17:09:57