Office JS setDataAsync函数内存泄漏

当在Excel 2016的Office js的共享API中使用asynchronous函数时,会导致内存泄漏,特别是调用binding.setDataAsnyc ,它永远不会释放写入的数据( 泄漏是在运行Excel中插件的Internet Explorer进程中一个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后的每个绑定,但内存仍然存在。 回收内存的唯一方法是重新加载插件。

我尝试了另一种分配值的方法:

 range.values = values; 

它不会泄漏,但要花费3倍于setDataAsync (对于1M行10列约为210秒),而setDataAsync需要约70秒,但是当然会泄漏,并在该请求中占用1.1 GB的内存。

我也试过table.rows.add(null, values); 但是性能更差。

我testing了相同的代码没有setdataAsync (立即调用),并没有发生内存泄漏。

其他人有没有经历过这个? 反正有它释放内存? 如果不是有另一种方法来填补Excel中的大量数据,除了这三种方法也是快速的?

添加一个绑定确实增加了内存消耗 – 但是只是调用setDataAsync绝对不应该(或者至less不会超过您的预期),或者通过手动将数据复制粘贴到表单中。

有一点要澄清:当你说:

我也试过table.rows.add(null, values)但是性能更差。

我假设你的意思是使用Excel.run(function(context) { ... });执行备用Office 2016-wave-of-API语法Excel.run(function(context) { ... }); ? 我可以跟进有关perf,但我很好奇,如果使用新的API语法以及内存泄漏发生。

FWIW,在接近未来的时候会有一个API允许您在设置数值时暂停计算 – 这应该会提高性能。 但是我想看看我们是否可以弄清楚你指出的两个问题: setDataAsyncrange.values调用的内存泄漏。

如果你能回答上面的问题(即使在range.values是否出现同样的泄漏),这将有助于缩小问题的范围,然后我会跟进团队。

谢谢!

我发现有一个布尔window.Excel._RedirectV1APIs ,你可以设置为true ,使setDataAsync使用新的API。 它应该被自动设置,如果

window.Office.context.requirements.isSetSupported("RedirectV1Api")

返回true,但不知何故该要求没有设置,但它的工作如果你手动设置

window.Excel._RedirectV1APIs = true

但它仍然比本机setDataAsync慢得多,但比range.values手动方法稍微快一些(160行比180行1M行range.values 10行),并且不会造成内存泄漏。

另外,我发现内存泄漏发生在ID为71( setDataAsnyc )的window.external.Execute(id, params, callback)函数之后,并且调用了该函数的callback函数,所以似乎内存泄漏以某种方式发生在/因为在Excel本身的外部代码(尽pipe内存泄漏是在Internet Explorer进程中)。 如果你短路,只是直接调用callback,而不是window.external.Execute没有发生内存泄漏,但当然,也没有设置数据。