R语言循环导入Feather文件时程序无报错随机挂起的问题咨询
循环调用arrow读取feather文件时无响应挂起的定位与解决
问题根因
该类无报错直接挂起的问题,本质和文件IO锁冲突、等待时长不足没有关系,核心是arrow包的原生层资源回收机制缺陷导致的:
- arrow包的核心读写功能是基于C层实现的,每次调用
read_feather()读取文件时,会在底层内存池申请专门的内存映射块来存储解析后的表格数据。R层的垃圾回收机制不会自动跟踪、释放这类C层申请的原生内存,循环迭代多次后,已用完的内存块如果没有主动触发回收,会持续占用系统内存资源。 - 当原生内存池的可用资源到达临界值时,底层C++层会进入无限等待资源释放的阻塞状态,不会向上层R抛出任何可捕获的错误,直接表现为R进程完全无响应。用户之前怀疑的文件打开冲突场景根本不会触发:arrow默认以只读模式打开feather文件,不设置排他锁,哪怕高并发重复读取同一个文件也不会出现IO阻塞,这也是延长
Sys.sleep()时长完全没有解决效果的原因。
可落地的解决方案
- 每轮读取完成后,主动触发R的垃圾回收流程,强制释放已无用对象占用的原生内存,修改后的示例代码:
library(arrow) rm(list = ls()) x <- 1 while (x < 50) { print(x) matches_for_prediction <- read_feather(<file_path>) # 主动触发垃圾回收,释放arrow占用的原生内存 gc() x = x + 1 Sys.sleep(2) }
- 不需要长期保留循环内读取的对象时,每轮数据处理完成后,将存储读取结果的变量手动赋值为
NULL,打断R的引用计数链,避免对象长期被挂载在工作环境中无法被回收。 - 长期运行的脚本建议将arrow包升级到11.0及以上版本,旧版本arrow存在公开的循环读取内存泄漏bug,高频重复调用
read_feather()时更容易触发挂起问题。
内容的提问来源于stack exchange,提问作者Jossy
相关产品推荐
相关产品推荐

