Lambda中使用pandas compare()触发numpy内存错误如何释放内存?
问题解答
1. 如何有效降低内存占用以支撑新DataFrame生成
- 优先做数据类型降级:你报错的待分配数组为float64类型,2697080行9列的float64数组刚好占用约185MiB内存,符合报错提示。如果业务精度允许,可将两个对比DataFrame的数值列从float64转换为float32,整数列根据取值范围转换为int32/int16,重复值占比高的字符串/数值列转换为
category类型,可直接降低50%以上的内存占用。 - 避免生成不必要的临时副本:
first_less_dupes[compare_columns]这类链式索引会生成临时DataFrame副本,额外占用内存。可改为直接调用compare的subset参数指定对比列,无需手动切片生成临时对象:df_compare = first_less_dupes.compare(second_less_dupes, subset=compare_columns)。 - 排查对象隐藏引用:你删除对象后内存未下降,大概率是这些对象仍被其他位置持有引用,比如
first_less_dupes/second_less_dupes是否和你删除的first等变量共享底层数组、对象是否被全局变量/容器(列表、字典)持有、是否被缓存逻辑引用。可将sys.getsizeof替换为pympler.asizeof查看对象全量内存占用,用gc.get_referrers(对象)查询剩余引用方。 - 分块处理:如果数据集仍超出内存限制,可将两个DataFrame按行拆分为多个分块,逐块对比后合并结果,避免全量数据同时加载到内存。
2. Lambda中是否可以和Windows系统一样监控当前内存使用
可以,你当前使用的psutil读取进程RSS的方式在Lambda的Linux运行环境中完全有效,print_current_memory函数逻辑正确,返回的就是当前进程实际占用的物理内存大小。此外你也可以直接读取/proc/meminfo系统文件获取全局内存使用情况,和Lambda运行日志中统计的函数最大内存占用指标完全对齐。
3. 删除对象的操作是否正确,gc调用方式是否合规
你的删除操作和gc.collect()调用语法均合规,未出现错误,但存在两个常见的认知误区:
- 你删除的
first、first_limited等变量如果是first_less_dupes的数据源,且Pandas衍生过程中未发生数据拷贝,二者会共享底层数组,删除原始变量不会释放内存,因为first_less_dupes仍持有底层数组的引用。 - 你遍历
locals()打印变量大小的逻辑如果运行在函数内部,仅能统计当前函数作用域的局部变量,全局作用域、闭包中持有的对象不会被统计到。
你可以在调用gc.collect()时打印其返回值,该值为本次回收的不可达对象数量,如果返回为0,说明你删除的对象仍有未解除的引用,无法被垃圾回收。
内容的提问来源于stack exchange,提问作者Liam Hanninen
相关产品推荐
相关产品推荐

