问题
我有一个包含大量公式的 .xlsx 文件。我想将此文件转换为新的 .xlsx 文件,其中所有公式都替换为其绝对值。为什么? 可能与这个问题无关。
我做了什么?
我的目标是在尽可能少的堆内存中执行此任务。所以我结合使用了apache POI XSSF event API读取源文件和 SXSSF API写入输出文件。效果很好。
观察结果
所有测量均使用 JProfiler 10 进行
当我运行代码来转换大约 25K+ 行的文件(包含大约 25K * 23 个公式)时,它在峰值时使用了大约 250 MB 的堆空间。现在,我使用 -Xmx24M
运行相同的命令,代码成功在此内存限制内运行,该内存限制明显低于第一次运行。
问题
- 如果我的代码已经可以在这么低的内存限制内运行,为什么第一次运行需要 250MB 以上的内存?
- 即使未设置 Xmx,是否可以限制这段特定的代码以将其内存消耗限制在较低的范围内?
最佳答案
垃圾收集器在第一次运行时没有立即释放内存。处理 XLSX 文件最终会生成大量 transient 对象,因此第一次运行会让它们在清理之前累积到大约 250MB;而第二个内存受限的运行则被迫更快地清理对象。
垃圾收集器有很多很多可以配置的选项和策略。我突然想到,我知道限制特定代码消耗的唯一方法是仅在其自己的 JVM 进程中运行该代码,并使用适当的 GC 参数。
关于java - 如何在不设置 -Xmx 标志的情况下限制堆消耗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44773264/