javascript - AngularJS 内存泄漏,即使在基本代码中
问题描述
我继承了一个 AngularJS 项目,其中显然存在内存泄漏。在生产环境中,如果运行了足够多的实例,导致浏览器崩溃就已经够糟糕的了,这可能会发生。
在过去的几天里,我读了很多关于 Javascript 中的泄漏,以及 AngularJS 中的陷阱。不幸的是,我仍然无法找到泄漏点。做我可能在 C 中做的事情,我把程序降到几乎没有,看看它是否还在泄漏。它很少,但它是一些东西。
如下面的代码所示,我每 10 秒访问一个端点……基本上只计算有效载荷中的键。没有什么花哨。我已经删除了所有正在使用的第 3 方模块。唯一应该在这里的是 Angular (1.5.8)、jquery 和 bootstrap。
我对谷歌开发工具并不精通,但我做了一些事情。1、是任务管理器。下面的代码似乎每隔几分钟就会泄漏大约 1k。(即使在我强制垃圾收集之后,JavascriptMemory 列中的“实时”值似乎也上升了 1k)。显然还不错,但作为一个主要的 schtick 不是前端(或者甚至是 Javascript)的人,我不确定这是否是预期/可以接受的。
其次,我拍摄了两个堆快照。(抱歉,代理禁止我使用我知道的任何图像托管程序)。我看到的主要内容是几分钟后,数组显示了 +1080 的大小增量。但是,我真的不知道我在寻找什么。
可以想象,当我们重新添加到生产代码中时,泄漏变得更加明显……甚至对最终用户也是如此。
任何帮助(甚至是一般帮助)都将受到赞赏。
泄漏测试.js
var app = angular.module('modal.editing', ['ngAnimate', 'ui.bootstrap'])
.controller('MainCtrl', MainCtrl);
function MainCtrl ($scope, $http, $q, $timeout) {
$scope.update_ms = 10000;
$scope.handle_data = function(data) {
console.log('Got ' + Object.keys(data).length + ' objects in handle_data()');
};
$scope.reload_entries = function() {
var the_url = '/api/1/list';
$http.get(the_url)
.success(
function (list) {
$scope.handle_data(list.data);
$timeout(function() { $scope.reload_entries(); }, $scope.update_ms);
})
.error(function volume_list_error_cb() {
$scope.addAlert('Error: GET /api/1/list; Can\'t get current volume list!', 'danger');
$timeout(function() { $scope.reload_entries(); }, $scope.update_ms);
});
};
$scope.reload_entries();
}
为简单起见,这里是生成的 HTML:
<!DOCTYPE html>
<html>
<head>
<title>Leak Test</title>
<link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/bootstrap/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="/stylesheets/style.css">
<script src="/jquery/jquery.min.js"></script>
<script src="/bootstrap/js/bootstrap.min.js"></script>
</head>
</html>
<body>
</body>
<script src="/angular/angular.js"></script>
<script src="/angular-animate/angular-animate.js"></script>
<script src="/angular-sanitize/angular-sanitize.min.js"></script>
<script src="/angular-ui-grid/ui-bootstrap-tpls-0.12.1.min.js"></script>
<a href="recon_grid">Recon Grid</a>
<h1>DC Recon by Traded Volume Grid</h1>
<h3 class="blue" id="d8_header">Last Update: Thu May 03 2018 13:40:57 GMT-0500 (CDT)</h3>
<div class="volume_grid_container">
<html ng-app="modal.editing">
<script type="text/ng-template" id="alert.html">
<div class="alert" role="alert">
<div ng-transclude></div>
</div>
</script>
<div alert ng-repeat="alert in alerts" ngMaxlength="3" type="{{alert.type}}" close="closeAlert($index)">{{alert.msg}}</div>
<body ng-controller="MainCtrl as vm">
</body>
</html>
</div>
<script src="/javascripts/leak_test.js"></script>
解决方案
推荐阅读
- assembly - uint32x2x2_t 和 int32x4_t 之间的 arm-neon 转换
- roku - 可以在海报节点和 Roku 中的其他节点上设置计时器..?
- apache-flink - 关于flink连接远程任务管理器报错的问题
- matlab - 并行实时图像采集和处理的最佳方法 (MATLAB)
- c++ - 为什么在以下情况下不需要对依赖类型使用 typename?
- php - 如何从 php 获取数据以添加 vue 的 json 数据?
- intellij-idea - 如何在 IntelIj Idea 中打开带有视图的底部工具窗口?
- docker - Dockerfile RUN mkdir 不创建文件
- error-handling - 从观察者内部的“下一个”函数调用“错误”
- python-3.x - 通过 REST API 创建 Keycloak 客户端