excel - Office JS setDataAsync 函数内存泄漏

标签 excel memory-leaks ms-office office-js office-addins

在 Excel 2016 的 office js 的共享 API 中使用异步函数时,会导致内存泄漏,特别是调用 binding.setDataAsnyc它永远不会释放写入的数据。( 泄漏是在 Internet Explorer 进程中运行 excel 中的插件(它是 32 位版本))。

例子 :

//1 Miliion row by 10 columns data parsed from a csv usually in chunks
var data = [];
var i,j;
for (i=0; i<1000000; i++) {
    row = [];
    for(j=0; j<10; j++) {
        row.push("data" + i + "" + j);
    }
    data.push(row);
}
var limit = 10000;
var next = function (step) {
    var columnLetter = getExcelColumnName(data[0].length);
    var startRow = step * limit + 1;
    var endRow = start + limit;
    if (data.length < startRow)
        return;
    var values = data.slice(startRow - 1, endRow - 1);
    var range = "A" + startRow + ":" + columnLetter + "" + endRow;
    Office.context.document.bindings.addFromNamedItemAsync(range,
        Office.CoercionType.Matrix, { id: "binding" + step },
        function (asyncResult) {
            if (asyncResult.status == "failed") {
                console.log('Error: ' + asyncResult.error.message);
                return;
            }

            Office.select("bindings#binding" + step).setDataAsync(values,
                {
                    coercionType: Office.CoercionType.Matrix
                }, function (asyncResult) {
                    //Memory keeps Increasing on this callback
                    if (asyncResult.status == Office.AsyncResultStatus.Failed) {
                        console.log("Action failed with error: " + asyncResult.error.message);
                        return;
                     }

                     next(step++);
                });
        });
    }

next(0);

我尝试在 setDataAsync 之后释放每个绑定(bind)但内存仍然存在。回收内存的唯一方法是重新加载插件。

我尝试了另一种将值分配给范围的方法:
range.values = values;

它不会泄漏,但需要的时间是 setDataAsync 的 3 倍(1M 行 x 10 列大约需要 210 秒)而 setDataAsync大约需要 70 秒,但在该请求中当然会泄漏并消耗 1.1 GB 的内存。

我也试过table.rows.add(null, values);但这有更糟糕的表现。

我在没有 setdataAsync 的情况下测试了相同的代码(立即调用 next )并且没有发生内存泄漏。

有没有其他人经历过这个?
无论如何,它周围有释放内存吗?
如果没有,除了这 3 种方法也很快,还有其他方法可以在 Excel 中填充大量数据吗?

最佳答案

添加绑定(bind)确实会增加内存消耗——但只需调用 setDataAsync绝对不应该(或者至少,不会超出您的预期,或者不会超过手动将数据复制粘贴到工作表中)。

需要澄清的一件事:当你说:

I also tried table.rows.add(null, values) but that's even worse performance.



我假设您的意思是使用 Excel.run(function(context) { ... }); 执行备用 Office 2016-wave-of-APIs 语法?我可以跟进 perf,但我很好奇当您使用新的 API 语法时是否也会发生内存泄漏。

FWIW,在不久的将来会有一个 API 允许您在设置值时暂停计算——这应该会提高性能。但我确实想看看我们是否能弄清楚你指出的两个问题:setDataAsync 上的内存泄漏。和 range.values称呼。

如果您可以从回答上述问题开始(即使在 range.values 中是否也会发生相同的泄漏),这将有助于缩小问题范围,然后我会跟进团队。

谢谢!

关于excel - Office JS setDataAsync 函数内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42909376/

相关文章:

python - XLWT 多种款式

java - java 对象的通用导出到 Excel

除非源工作簿打开,否则 Excel 链接不起作用?

javascript - 如何在 javascript 中检测已安装的 MS Office 版本?

templates - 在 Word 2013 中添加自定义 "template group"

c# - Excel 2013 插件 API 是否向后兼容 Excel 2003-2010?

c# - 如何在 net.core 3.1 中连接打开的 excel 应用程序?

c++ - 什么时候 boost::shared_ptr 可能不会被释放?

memory-leaks - AudioToolbox 库 AVAudioPlayer 中的内存泄漏

linux - 为什么 Valgrind 没有显示 Rust 程序的分配?