Angular:并发下载后的内存泄漏?
|
我正在开发一个Angular应用程序,我创建了一个这样的下载页面:
如果我查看Chrome任务管理器,我会发现与我的应用程序相关的进程会保留大约130 MB的内存. 然后,用户可以单击每个下载按钮启动同时下载(总文件大小为266 MB):
现在,如果我再次检查任务管理器,我会看到内存使用量增加,当所有下载完成后,其峰值大约为650 MB. 初始内存使用量2 *总文件大小=最终内存使用量 130 MB 2 * 266 MB = 130 MB 532 MB = 662 MB = ~650 MB. 如果我尝试使用Chrome垃圾收集器,它会减少大约30 MB,但我仍然拥有620 MB作为内存使用量的应用程序. 这是当我单击文件的下载按钮(从下载页面)时调用的函数: getFile(file: any): void {
this.fileDownloadService.downloadFile(file).subscribe(
(fileinfo: SispFile) => {
file.downloading = true;
},(err: any) => {
file.downloading = false;
console.log('errore',err);
},() => {
file.downloading = false;
console.log('completated');
});
}
这是FileDownloadService中的downloadFile函数,由getFile调用: downloadFile(file: SispFile): Observable<any> {
let conf: any = {};
conf.totalChunks = Math.max(Math.ceil(file.size / this.chunkSizeDownload),1);
conf.mime = file.extension;
conf.currentChunk = 0;
conf.byteDownloaded = 0;
conf.chunkSizeDownload = this.chunkSizeDownload;
conf.chunkBlobs = [];
conf.finalBlob = null;
file.progress = 0;
return new Observable(observer => {
observer.next(file);
this.addChunk(file,observer,conf);
})
}
addChunk(file: SispFile,observer: any,conf: any) {
if (conf.currentChunk == conf.totalChunks) {
observer.complete();
conf.finalBlob = new Blob(conf.chunkBlobs,{type: conf.mime});
let fileURL = URL.createObjectURL(conf.finalBlob);
let a = document.createElement("a");
a.href = fileURL;
a.download = file.name;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(fileURL);
} else {
this.docService.downloadFile(file,conf.chunkSizeDownload,conf.byteDownloaded)
.then(response => {
let typedArray = this.createBlob(response['_body'],conf.mime);
conf.chunkBlobs[conf.currentChunk] = typedArray;
conf.currentChunk++;
conf.byteDownloaded = conf.currentChunk * conf.chunkSizeDownload;
if (conf.Downloaded + this.chunkSizeDownload > file.size) {
conf.chunkSizeDownload = file.size - conf.Downloaded + 1;
}
let progress = Math.round((conf.currentChunk * 100) / conf.totalChunks);
file.progress = progress;
observer.next(file);
this.addChunk(file,conf);
})
.catch((error: ErrorMessage) => {
observer.error(error);
console.log('Errore server: ' + error);
});
}
}
这是对DocService中后端端点的最终调用: downloadFile(file: SispFile,length: number,offset: number) {
let url = Util.format(this.downloadFileUrl,{id: file.id});
let body: any = { "downloadMode": "PAYLOAD","fileId": file.id,"length": length,"offset": offset };
return this.http.post(url,body)
.toPromise()
.then(response => {
return response;
})
.catch(this.handleError);
}
解决方法
我发现Angular有这个
Testability类.它的定义是:
您可以通过 正如我们在this issue中所看到的,销毁组件不会释放浏览器的内存,因为Testability API不会释放它的引用. 所以,也许,通过清除TestabilityRegistry on destroy可以帮助你摆脱那些总结导致你的620MB内存泄漏的引用. 这是我发现的the fix! 我希望这有助于解决您的问题,或者至少我希望我能够设法给您一个不同的观点或新的研究领域! 更新: 从我所看到的,为了清理TestabilityRegistry: 在modules/@angular/core/src/testability/testability.ts中: destroy(): void {
this._applications.clear();
testabilityGetter.onDestroy();
}
这将是破坏方法. 在modules/@angular/core/src/application_ref.ts中: this._injector.get(TestabilityRegistry).destroy(); 我们调用destroy方法. 在modules/@angular/platform-b??rowser/src/browser/testability.ts中: onDestroy(): void {
delete global.getAngularTestability;
delete global.getAllAngularTestabilities;
delete global.getAllAngularRootElements;
delete global.frameworkStabilizers;
}
在销毁时,我们确保删除可测试性实例. 看看this commit.它向您展示了如何清理TestabilityRegistry. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


