我正在尝试用Cordova和AngularJs编写一个iPad应用,它会在启动时自动更新。因此我复制了很多文件(js,css,图像,...)当应用程序过期时。
在iPad-App冻结了大约400个文件之后,将不再处理延迟事件。我已经剥离了我的应用程序,并来到这个测试应用程序,它基本上是连续10000次初始化文件系统:
<!-- language: lang-js -->
angular.module('tablet', []).controller('StartCtrl', ['$scope', '$http', '$q',
function($scope, $http, $q) {
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
console.log('deviceready');
testFileSystem($q);
}
}
]);
function testFileSystem($q) {
var defer = $q.defer();
var chain = defer.promise;
defer.resolve();
// chaining 10000 init filesystem requests
for (var i = 0; i < 10000; i++) {
chain = chain.then(startInitFileSystem($q, i));
}
}
function startInitFileSystem($q, i) {
return function() {
return initFileSystem($q, i);
}
}
function initFileSystem($q, i) {
console.log('Init FileSystem: ' + i);
var defer = $q.defer();
window.requestFileSystem(PERSISTENT, 1024 * 1024 * 1024, function(fs) {
fileSystem = fs;
defer.resolve();
}, function() {
console.log("Init FileSystem failed");
defer.reject();
});
return defer.promise;
}在997请求应用程序停止后,不再触发任何延迟事件。在调试angularjs defer对象时,我可以将问题范围缩小到方法:
<!-- language: lang-js -->
self.defer = function(fn, delay) {
var timeoutId;
outstandingRequestCount++;
try {
timeoutId = setTimeout(function() {
delete pendingDeferIds[timeoutId];
completeOutstandingRequest(fn);
}, delay || 0);
} catch (e) {
console.log(e.message);
}
pendingDeferIds[timeoutId] = true;
return timeoutId;
};会调用setTimeout,但不会在出错时触发。
这会不会是某种内存泄漏?令人惊讶的是,如果你不使用角度延迟,它就能正常工作。在延迟解决后,有没有办法清理它?
我使用的是cordova插件:设备、记录器和文件。
发布于 2015-01-08 20:27:08
我也有同样的问题。问题是您的内存正在运行,这是由iOS设备上的setTimeout发生泄漏的完全原因。
您可以通过使用工具和运行分配工具来验证这一点。在真实设备上运行您的示例并连接到该进程。在连接时运行您的示例。您应该会看到一个不断增长的分配图。当您在不使用任何setTimeout调用的情况下重新实现示例时,垃圾收集器将按其应有的方式清除所有内容。请注意,垃圾收集有点懒惰,只有在分配了一定数量的内存后才会启动。所以你需要重新运行你的代码。
我的示例代码是在创建测试cordova项目时添加到app对象的:
run: function () {
function error(err) {
alert(err);
}
window.requestFileSystem(window.PERSISTENT, 0, function (fs) {
function tick(i) {
return function () {
if (i > 1000) return;
fs.root.getDirectory(String(i), { create: true }, function () {
setTimeout(next(i + 1), 0); // Removing setTimeout solves the memory leak
}, error);
};
}
tick(0)();
}, error);
}注意,即使函数已经完成处理,内存分配也会保持不变,如果没有setTimeout,内存将在进程完成后被垃圾回收。我目前不知道为什么会发生这种情况,但如果它真的与setTimeout调用有关,应用程序中的每个调用都可能导致泄漏。
https://stackoverflow.com/questions/27483000
复制相似问题