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. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |