我们有一个 Coldfusion 应用程序,它正在运行一个大型查询(最多 100k 行),然后以 HTML 格式显示它。然后,用户界面提供了一个导出按钮,该按钮触发使用 cfspreadsheet 标记和电子表格函数将报告写入 .xlsx 格式的 Excel 电子表格,特别是用于构建行列值的电子表格SetCellValue、用于格式化的电子表格格式行和电子表格格式单元函数。然后使用以下命令将 ssObj 写入文件:
<cfheader name="Content-Disposition" value="attachment; filename=OES_#sel_rtype#_#Dateformat(now(),"MMM-DD-YYYY")#.xlsx">
<cfcontent type="application/vnd-ms.excel" variable="#ssObj#" reset="true">
其中 ssObj 是 SS 对象。我们看到文件大小约为 5-10 Mb。
但是...创建此报告和写入文件的内存使用量增加了大约 1GB。复杂的问题是,java GC 在导出完成后没有立即释放内存。当我们有多个用户运行并导出这种类型的报告时,内存不断攀升并达到分配的堆大小并杀死服务器的性能,从而导致服务器停机。通常需要重新启动才能将其清除。
这是正常/预期的行为还是我们应该如何处理这个问题?是否可以在导出完成后按需轻松释放此操作的内存使用量,以便运行报表的其他人轻松访问为他们的报表释放的空间?这种类型的内存使用对于 5-10Mb 文件是否常见于 cfspreadsheet 函数并写出对象?
我们已尝试暂时删除昂贵的格式化功能,但创建和写入 .xlsx 文件的内存使用量仍然很大。我们还尝试使用电子表格添加行方法和 cfspreadsheet action="write" query="queryname" 标记传入查询对象,但这也占用了大量内存。
为什么这些函数如此占用内存?在没有内存不足问题的情况下生成 Excel SS 文件的最佳方法是什么?
我应该添加服务器在 Windows 上的 Apache/Tomcat 容器中运行,我们使用的是 CF2016。