在使用 Google 地图时遇到过类似问题,我试图隔离一个最小的测试用例。我想看看这是否是一个更普遍的内存管理问题。
这段代码仅在数组中存储随机数据,导致 iPad mini 上 IOS 7 上的 Safari 崩溃,16GB:
function randomString(length, chars) {
var result = '';
for (var i = length; i > 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))];
return result;
}
var arr = []
for (var i=0;i<5000;i++) {
// one character is two bytes in JavaScript, so 512 chars is 1Kb:
o = randomString(512, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
arr.push(o);
}
您可以通过 http://vici.org/memtest.html 使用自己的浏览器尝试此测试。该页面上的脚本将尝试以 1Mb 为步长申请 50Mb 的内存。该脚本显示了一个正在运行的计数器,因此您将看到浏览器的执行情况以及它何时崩溃(如果确实如此)。该脚本将每个 ip / 用户代理组合的结果存储在数据库中,以便能够得出一些结论。
平均而言,IOS 6 (n=12) 允许脚本占用大约 12Mb。 IOS 7 (n=47) 允许脚本要求大约 15 Mb。这些不是硬性限制。两组的标准偏差都非常高,约为 12 Mb。在 Xcode 模拟器中,Safari 甚至根本不会崩溃(声称完整的 50Mb,可能是因为它可以访问更多 RAM)。
因此我们可以得出结论,该问题不是由于 IOS 7 为 Safari 留出的内存减少所致。正如 Philipp Kühn 所建议的那样,问题似乎是——在某些特定情况下? - 与 IOS 6 相比,Safari 消耗的内存明显更多。关于原因的一条线索可以在 https://discussions.apple.com/message/23837361#23837361 找到,其中一个页面有 200 个 div 和以下 CSS
div {
-webkit-backface-visibility: hidden;
}
Safari 崩溃。
使用 Leaflet 库似乎可以规避地图问题(请参阅https://code.google.com/p/gmaps-api-issues/issues/detail?id= 和 https://github.com/Leaflet/Leaflet/pull/2149),但 Leaflet 不是通过更改 css 而是通过更改 javascript 级别来规避内存不足的崩溃。传单现在规避像
这样的陈述
context = this
这表明 Safari 不会清理未使用的对象。只要 Apple 不修复 Safari,也许 Google 可以做出类似于 Leaflet 家伙所做的改变?
与此同时,Apple 发布了 IOS7.1,它并不能完全解决崩溃问题,但肯定会降低崩溃的发生频率。