上传和操作多个文件时的内存使用率很高
我想使用FineUploader来上传大量文件。我还需要在上传文件之前操作这些文件 - 即我需要匿名一些识别信息。在another answer中,Ray Nicholus建议在onSubmit处理程序中拒绝原始文件,然后重新添加操作文件。所以我的onSubmit处理程序看起来像这样:上传和操作多个文件时的内存使用率很高
onSubmit: function (id, name)
{
var file = this.getFile(id)
if (file.isAnonymized)
{
return;
}
var reader = new FileReader()
reader.onload = function()
{
var arrayBuffer = this.result
var byteArray = new Uint8Array(arrayBuffer)
// Manipulate the byteArray in some way...
var blob = new window.Blob([byteArray])
blob.isAnonymized = true
// add the anonymized file instead
uploader.addFiles({blob: blob, name: name})
}
reader.readAsArrayBuffer(file)
// cancel the original file
return false
},
这适用于少量的文件。在一个具体的例子中,一位客户试图在Firefox中上传〜1.500个3MB的文件,并且在标签最终崩溃之前看到Firefox的内存使用率高涨。其他浏览器(Chrome,Edge)表现出类似的行为。使用浏览器的开发人员工具似乎没有显示任何大的内存分配。按原样上传文件时没有问题,但这不是一个选项。
我在https://github.com/sgarcialaguna-mms/file-upload-memory/的某处清理了一下这个例子,现在我确信这个错误是由于fineuploader库持有blob超过需要的时间。
该示例现在一次将一个文件加载到内存中,然后将blob传递到上传库。我现在也使用实际的服务器(来自fineuploader服务器示例存储库的Django示例)。
使用Firefox时,当我拖入大约1GB的文件时,即使上传完成后,Firefox的内存使用量也会在上传过程中稳步上升并保持在较高水平。我可以打开about:memory,点击“Minimize memory usage”触发垃圾回收,按下“Measure”,文件数据显示在“memory-file-data/large”下。调用,再次触发垃圾回收,Firefox的内存使用量急剧下降。再次测量显示“内存文件数据/大”对象不再存在于内存中。根据https://github.com/FineUploader/fine-uploader/issues/1540#issuecomment-194201646,每次上传后都会调用this._handler.expunge(id)
。
Chrome的行为有点不同,由于长期存在的bug,一旦超过500 MB的blob数据累积,它最终开始抛出ERR_FILE_NOT_FOUND错误。 chrome:// blob-internals页面显示哪些blob正在被保存以及它们的refcount。
我不知道是否有一个简单的方法来告诉哪些变量/闭包/任何持有这些对象,但它会非常有帮助。
文件不占用内存,它们由磁盘支持。保持这些文件不会消耗内存。但是,如果您传递的Blob不受磁盘上的文件支持,则这是一个不同的故事。我不知道任何Fine Uploader将会持续超过必要时间的区域。为了确信情况是这样的,需要探索代码,并且需要揭示问题出现的位置。 –
最有可能的问题在于你的代码。如果将1 GB内存支持的Blob传递给Fine Uploader,当然这会消耗1 GB的内存,并且Blob必须保持在范围内直到它们被上传。 –
好吧,我最后的评论,因为我将在今年剩余时间内无法上网。 @ RayNicholus“最有可能的问题出现在你的代码中,如果你将1GB内存支持的Blob传递给Fine Uploader,当然这会消耗1GB内存,并且Blob必须保留在范围内已上传“。这很明显。正如我明确指出的那样,问题在于上传后内存不会被释放。 “很可能,问题出在您的代码中。”我的代码就在那里。它几乎只有60行。如果你能发现我犯的错误,我会很乐意听到它。 –
您可能会考虑以某种方式将其放入WebWorker中。 – TryingToImprove
某些js文件库不是用来管理大量文件的。 XMLHttpRequest是巨大的异步对象。通常情况下,当你放入超过1000个文件时(因为它分配并尝试启动1000个同时连接),这种类型库会在for循环中启动所有上传操作,挂起浏览器。我建议你写自己的上传部分。 – Fefux
就像我说过的,只是上传作品就像一个魅力,所以我很有信心,这不是问题。这是当我需要事先处理文件时,疼痛开始。 –