【发布时间】:2011-12-29 20:23:48
【问题描述】:
我们有一个 ColdFusion 9 脚本,它会定期运行,读取 CSV 文件并将记录插入到 Oracle 11g 数据库中。 CSV 文件大约有 50 列,其中 8 列由 CF 使用(CSV 格式不能修改)。 CFM的一般流程是:
- 将文件读入变量
- CFLOOP 使用该变量作为列表属性,并以 CHR(13) 作为分隔符
- 调用 Oracle 存储过程,使用 ListGetAt 从文件中插入各种值
存储过程执行以下操作:
- 将具有 2 个字段的记录插入到表 1 中
- 在表 2 中插入一条有 8 个字段的记录(包括表 1 的主键)
- 不返回任何内容
这在大多数情况下都能成功运行,只需几秒钟即可读取包含数百条记录的 400 KB 文件。但是,有时我们会得到一个大容量并最终得到一个 13k 记录的 5MB 文件。当我们尝试处理这么大的文件时,我观察到 JVM 内存使用量在 10-15 秒内从 90MB 上升到大约 680MB,之后 CF 服务器监视器停止响应(就像 CF 一样),迫使我们重新启动服务。日志报告 JVM 内存不足错误:
"错误","qtp4795249-38798","12/28/11","16:29:20","超出 GC 开销限制" java.lang.OutOfMemoryError: 超出 GC 开销限制
我们的 JVM 堆大小目前为 768MB。我没有尝试增加它,因为即使这确实解决了这个问题,它也不能在未来保护我们,并且服务器的其余正常负载几乎不需要那么多。而且对于需要重启才能在生产机器上生效的 JVM 设置,我犹豫不决。
这很难测试,因为导入过程运行良好,在我的本地开发机器和我们的 QA 机器上几乎没有任何明显的内存负载,但它们与数据库的连接速度要慢得多,需要 10-15 分钟完成。
我会很感激任何想法,尤其是关于记忆去向的想法。我无法弄清楚 5MB 的数据是如何变成 700 MB 的数据的。我们确实打开了调试信息,但调用脚本的 IP 地址不在调试列表中,我使用 cfsetting 标签关闭了此页面的调试。以前有一个步骤 1.5 将 CSV 数据转换为 ColdFusion 查询,但我为了提高效率而取消了它。两种方式都会导致 oom 错误。
【问题讨论】:
-
感谢所有回复。由于客户的月末和年终处理,以及他们昨天将 CF 服务器关闭 30 秒的响应,我们将等待一周左右,然后再尝试实施或测试任何这些建议。我会更新这个问题。
标签: csv coldfusion