V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hhhhhh123
V2EX  ›  程序员

Python 读取 500M .pkl 文件,却用了 8 G 内存

  •  
  •   hhhhhh123 · 2022-09-29 16:03:45 +08:00 · 2147 次点击
    这是一个创建于 788 天前的主题,其中的信息可能已经有所发展或是发生改变。
    # 500M pkl
    with open(f'{abs_static_file_path}/pkl/wr_TURN.pkl', 'rb') as f:
        wr_RIVER = pickle.load(f)
    print(sys.getsizeof(wr_RIVER) / 1024 / 1024)
    # result 160.00009155273438
    

    服务器却用了 8G 内存。这是有什么说法吗?

    一共三个 pkl 文件, 大概一共不到一个 G , 全部运行 服务器 python 使用了 12 个 G 运行内存。

    10 条回复    2022-09-30 14:49:50 +08:00
    Lockeysama
        1
    Lockeysama  
       2022-09-29 16:20:47 +08:00   ❤️ 1
    正常吧,反序列出来后变成各种数据类型、变量,Python 本身又是万物皆对象。。肯定大的
    lookStupiToForce
        2
    lookStupiToForce  
       2022-09-29 16:34:45 +08:00   ❤️ 1
    问一下,你打印 sys.getsizeof(wr_RIVER) / 1024 / 1024 底下的注释是 160.00009155273438 ,直接理解不应该只用了 160MB 内存嘛? 8g 内存是你看 python 进程消耗看到的?
    jones2000
        3
    jones2000  
       2022-09-29 20:36:05 +08:00
    要想内存用的少用 c++。
    julyclyde
        4
    julyclyde  
       2022-09-30 08:34:13 +08:00
    加载前后分别看一下 /proc/pid/smaps 做对比
    hhhhhh123
        5
    hhhhhh123  
    OP
       2022-09-30 09:32:15 +08:00
    @lookStupiToForce 是的 进程看到是 8G 内存
    hhhhhh123
        6
    hhhhhh123  
    OP
       2022-09-30 09:32:59 +08:00
    @jones2000 cpython 是 C++ 写的呀
    hhhhhh123
        7
    hhhhhh123  
    OP
       2022-09-30 09:35:12 +08:00
    @lookStupiToForce 我理解也是应该是使用 160M 内存, 但是进程查看是用八个 G 就只是运行加载文件
    lookStupiToForce
        8
    lookStupiToForce  
       2022-09-30 09:49:53 +08:00
    @hhhhhh123 #7 简单点的方法你可以把 globals() 和 locals() 列出的对象都 getsize 看一下,是不是哪一个中间调用的包占了这么大内存
    复杂点的方法你得上 memory profiler ,然后手动 import 一遍你 load 时可能用到的包(还是可以根据 global()和 locals()列出的项目进行 import ),看是哪一个包在调用的时候往内存里塞了大量占空间的静态变量
    pzhdfy
        9
    pzhdfy  
       2022-09-30 11:06:02 +08:00
    @hhhhhh123
    不是这样算的 openjdk 还是 c++写的呢
    需要按照 pod 这类 c/c++原生内存布局才能省空间
    cpython 的都是一堆对象,对象相互引用,每个对象额外的 overhead 特别大。
    举个简单的例子 java 里面 int[] 和 Intager[] 的内存占用和计算速度差很大
    wcsjtu
        10
    wcsjtu  
       2022-09-30 14:49:50 +08:00
    getsizeof 不会递归统计内存,你得到的只是最外层容器的内存占用值。自己写个函数去递归统计吧,这样的数据才是相对准确的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3236 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 12:59 · PVG 20:59 · LAX 04:59 · JFK 07:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.