使用python进行大量的文件IO读写,压缩,复制,数据操作过程中RES占用(0.2G-5G,Python的GC会频繁地malloc/free),发现RES内存不释放。
- 排查代码后,没有发现内存泄露的情况(实际上有泄露,但是修改代码后,依然没有解决本文的问题),GC也是默认开启的。
- 使用tracemalloc,objectgraph调试,Python对象的产生和释放并没有啥异常,我们使用的是大对象,应该也不会被Python缓存。
- 考虑到代码中使用pandas.DataFrame,Google发现类似的问题,还有issue,发现可能是Glibc优化问题。
- 将数据容器改为Python内置类型list,dict,我们使用简单的Python脚本,持续频繁进行大对象的生成和释放,发现还是有问题。实际调测中也发现,这个问题给人的整体感觉不是代码哪里有问题,而是哪里有人做了优化,但是Python的对象内存管理是基于引用计数的(refcnt为0直接decref回收),python内存池也没发现大内存驻留,操作系统brk和mmap也并没有不释放内存,只能是C库的问题了)。没法继续定位了,需要太多时间成本了。
- 那么我们在Python中如何手动分配释放内存?我们使用进程内存隔离的能力直接管理内存,父进程只负责进程池管理,子进程干完事情,直接退出,或过期重新拉起,或者超过内存阈值就干掉,就可以了。(虽然很麻烦,但是如果你需要大量的进程处理数据,每个进程的内存有很大数据吞吐量,那么整体过高的内存占用,会影响其他服务的服务能力)。