在 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/