Angular 角度:并发下载后内存泄漏?
我正在开发一个Angular应用程序,并创建了如下下载页面: 如果我看一下Chrome任务管理器,我会发现与我的应用程序相关的进程保留了大约130MB的内存 然后,用户可以单击每个下载按钮同时启动下载(总文件大小为266MB): 现在,如果我再次检查任务管理器,我会看到内存使用量增加,当所有下载完成时,其峰值约为650 MB。 我注意到一件奇怪的事情:内存的最终使用似乎是以下公式的总和: 初始内存使用率+2*总文件大小=最终内存使用率 130MB+2*266MB=130MB+532MB=662MB=~650MB。 如果我尝试使用Chrome垃圾收集器,它会减少大约30MB的内存,但我仍然有620MB的内存使用量。 那么,我如何纠正这种行为呢?你能看出我的代码有什么问题吗? (我曾尝试在组件的Angular 角度:并发下载后内存泄漏?,angular,memory-leaks,download,observable,Angular,Memory Leaks,Download,Observable,我正在开发一个Angular应用程序,并创建了如下下载页面: 如果我看一下Chrome任务管理器,我会发现与我的应用程序相关的进程保留了大约130MB的内存 然后,用户可以单击每个下载按钮同时启动下载(总文件大小为266MB): 现在,如果我再次检查任务管理器,我会看到内存使用量增加,当所有下载完成时,其峰值约为650 MB。 我注意到一件奇怪的事情:内存的最终使用似乎是以下公式的总和: 初始内存使用率+2*总文件大小=最终内存使用率 130MB+2*266MB=130MB+532MB=66
ngondestory
上使用unsubscribe
,但无效)
以下是当我单击文件的下载按钮(从下载页面)时调用的函数:
以下是FileDownloadService
中的downloadsfile
函数,由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, observer, conf);
})
.catch((error: ErrorMessage) => {
observer.error(error);
console.log('Errore server: ' + error);
});
}
}
我发现Angular有这个类。它的定义是: 可测试性服务提供可访问的测试挂钩 通过浏览器和诸如量角器之类的服务。每个都是自举的 页面上的Angular应用程序将具有可测试性实例 您可以通过访问特定元素的可测试性实例的全局注册表 正如我们在中所看到的,销毁组件不会释放浏览器的内存,因为可测试性API不会释放它的引用 因此,也许,通过清理destroy上的TestabilityRegistry可以帮助您摆脱那些导致620MB内存泄漏的引用 这是我找到的 我希望这有助于解决你的问题,或者至少我希望我能设法给你一个不同的观点或一个新的研究领域 更新: 据我所见,为了清理
可测试性注册表
:
在modules/@angular/core/src/testability/testability.ts中:
destroy(): void {
this._applications.clear();
testabilityGetter.onDestroy();
}
this._injector.get(TestabilityRegistry).destroy();
onDestroy(): void {
delete global.getAngularTestability;
delete global.getAllAngularTestabilities;
delete global.getAllAngularRootElements;
delete global.frameworkStabilizers;
}
这将是销毁方法
在模块/@angular/core/src/application\u ref.ts中:
destroy(): void {
this._applications.clear();
testabilityGetter.onDestroy();
}
this._injector.get(TestabilityRegistry).destroy();
onDestroy(): void {
delete global.getAngularTestability;
delete global.getAllAngularTestabilities;
delete global.getAllAngularRootElements;
delete global.frameworkStabilizers;
}
我们调用destroy方法
在modules/@angular/platform browser/src/browser/testability.ts中:
destroy(): void {
this._applications.clear();
testabilityGetter.onDestroy();
}
this._injector.get(TestabilityRegistry).destroy();
onDestroy(): void {
delete global.getAngularTestability;
delete global.getAllAngularTestabilities;
delete global.getAllAngularRootElements;
delete global.frameworkStabilizers;
}
销毁时,我们确保删除可测试性实例
看看。它向您展示了如何清理可测试性注册表。感谢您的提示。那我该怎么办呢?我看到修复程序没有合并到Angular master repository。@smartmouse我相信您可以首先将其分叉并测试它是否修复了您的问题。也许你可以调整forked repository直到它满足你的需要。如果我尝试fork,那么你知道如何清理
TestabilityRegistry
?我确实看到了提交,我误解了你的答案,那么如果我将此修复应用到我的组件中,就没有必要在我的组件中执行任何操作。。。现在,我正在尝试将这些更改应用到我的存储库中……我确实尝试过使用修复程序,但它无法解决我的问题。无论如何,谢谢你的支持。(这是我修改的角度:)