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

2022-09-29 16:03:45 +08:00
 hhhhhh123
# 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 运行内存。

2175 次点击
所在节点    程序员
10 条回复
Lockeysama
2022-09-29 16:20:47 +08:00
正常吧,反序列出来后变成各种数据类型、变量,Python 本身又是万物皆对象。。肯定大的
lookStupiToForce
2022-09-29 16:34:45 +08:00
问一下,你打印 sys.getsizeof(wr_RIVER) / 1024 / 1024 底下的注释是 160.00009155273438 ,直接理解不应该只用了 160MB 内存嘛? 8g 内存是你看 python 进程消耗看到的?
jones2000
2022-09-29 20:36:05 +08:00
要想内存用的少用 c++。
julyclyde
2022-09-30 08:34:13 +08:00
加载前后分别看一下 /proc/pid/smaps 做对比
hhhhhh123
2022-09-30 09:32:15 +08:00
@lookStupiToForce 是的 进程看到是 8G 内存
hhhhhh123
2022-09-30 09:32:59 +08:00
@jones2000 cpython 是 C++ 写的呀
hhhhhh123
2022-09-30 09:35:12 +08:00
@lookStupiToForce 我理解也是应该是使用 160M 内存, 但是进程查看是用八个 G 就只是运行加载文件
lookStupiToForce
2022-09-30 09:49:53 +08:00
@hhhhhh123 #7 简单点的方法你可以把 globals() 和 locals() 列出的对象都 getsize 看一下,是不是哪一个中间调用的包占了这么大内存
复杂点的方法你得上 memory profiler ,然后手动 import 一遍你 load 时可能用到的包(还是可以根据 global()和 locals()列出的项目进行 import ),看是哪一个包在调用的时候往内存里塞了大量占空间的静态变量
pzhdfy
2022-09-30 11:06:02 +08:00
@hhhhhh123
不是这样算的 openjdk 还是 c++写的呢
需要按照 pod 这类 c/c++原生内存布局才能省空间
cpython 的都是一堆对象,对象相互引用,每个对象额外的 overhead 特别大。
举个简单的例子 java 里面 int[] 和 Intager[] 的内存占用和计算速度差很大
wcsjtu
2022-09-30 14:49:50 +08:00
getsizeof 不会递归统计内存,你得到的只是最外层容器的内存占用值。自己写个函数去递归统计吧,这样的数据才是相对准确的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/883838

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX