重启iOS设备时会释放什么?

3

简短问题

我有一个bug,只有在重新启动设备后才会消失。我想知道在重新启动iOS设备时释放了什么,以便对我的bug有一定的了解。 释放我的缓存和我的RAM并不能帮助我修复我的bug,所以我想知道还有什么其他东西可以释放来暂时修复我的bug。

背景

我有一个使用WebGL和BabylonJS的web应用程序,在所有设备和浏览器上都可以正常工作,除了iOS。使用Safari时,我总是最终收到错误消息“发生了问题,因此重新加载了这个网页”。

这发生在运行iOS 10.3.3的iPad Air 2(2Go RAM)上,但我在我手中拥有的每个iOS设备上都看到了相同的bug。这就是为什么我认为这是与iOS相关的唯一原因。 我知道iOS资源限制:https://dev59.com/5WEh5IYBdhLWcg3ww11p#22193143

我已经尝试了数月调试此问题,这个bug会随机出现,有时很快,有时很慢。没有任何一致的东西,所以它是完全不可能进行调试的。

最好的猜测是这是一个内存问题,因为崩溃似乎每次出现得更快。而且因为错误消息几乎总是与内存问题相关联。
我怀疑纹理和renderTargetTextures会占用越来越多的内存(但我不明白为什么它不会被释放,我没有保留无用的引用)。
但有一件事我很确定:当我重新启动我的设备时,它总是第一次工作(直到我重新加载一次,然后开始下降螺旋)。
如果我清除缓存(通过设置-> Safari)和我的RAM(在关闭屏幕时按home键),这个错误仍然存在。但是如果我重新启动我的设备,它就消失了。某些内存中的东西被释放了,我想知道是什么。
但我也可能完全错了,它可能是内存之外的东西,我对你们所有的建议都持开放态度。
提前感谢,这让我疯狂了数月!
更新:
这是JS Heap的样子:

JS Heap

更新2

在iOS上,每帧请求90个渲染目标纹理的场景(379x890像素)确实有效。 如果我不请求任何渲染目标纹理,则我的应用程序可以正常工作。但是,如果我只请求每帧一个小的渲染目标纹理,它会更快地崩溃。 从这个观察中能得出什么结论?这是否支持或否定了内存问题的想法?

更新3

以下代码没有明显的问题原因,但是注释/取消注释通常会使错误消失/出现。

var texture = generateTexture();
function generateTexture() {
    var rt1 = new BABYLON.RenderTargetTexture("rt1", { width: scene.getEngine().getRenderWidth(), height: scene.getEngine().getRenderHeight() }, scene, false, true, scene.getEngine().TEXTURETYPE_UNSIGNED_BYTE, false);
    rt1.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE;
    rt1.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE;
    rt1.renderList.push(sphere);
    rt1.onBeforeRender = function() {
        sphere.material = std1;
    };
    scene.customRenderTargets.push(rt1);
    return rt1;
}

我可以坚持这段代码在更新2中发布的链接中有效,所以我认为这段代码不相关。唯一的问题是,注释掉应用程序的这部分似乎可以消除随机错误。 这段代码要求3D引擎在渲染到屏幕之前将其渲染到一个中介纹理中。因此,这段代码会影响每一帧。 在链接中,我要求引擎在渲染到屏幕之前将纹理渲染90次。

更新4:问题已解决

问题不取决于iOS重新启动时发布的内容,因此我无法回答自己的问题。但我可以说iOS不喜欢动态照明。 从现在开始,我们所有的项目都将在iOS设备上限制为一个光源。

更多的灯光,每帧计算量就越大。这对于iOS来说太多了,在短时间内要求太多的内存的应用程序将被终止。


1
请展示一些代码以便于更轻松地调查问题。 - Tamás Sengel
无法隔离错误,它会随机出现。而且代码太大了。这就是为什么我不会请求任何人来修复我的错误,因为我无法展示任何相关的代码。抱歉。 由于这是一个WebGL应用程序,在每一帧中都会生成和释放纹理。这可能解释了为什么内存问题会随机出现,而不总是在同一时刻。 - MrBooks
仅提供帮助,如果可能,请尝试使用用户配置文件并获取内存泄漏。 - Gagan_iOS
当我浏览类似macrumors.com的常规网站时,我经常看到这个错误。 - meaning-matters
当进行性能分析时,我觉得一切都很正常。内存会增加直到下一次垃圾回收等等...它从未达到iOS资源限制。其他正常运行的3D网络应用程序给我相同类型的结果。 - MrBooks
请查看 https://dev59.com/IJrga4cB1Zd3GeqPrsI- - Vini App
1个回答

3

如果没有看到您的代码,我不能保证提供任何解决方案,但我可以提供一些有关内存问题的信息。

如果你确定第一次加载时不会崩溃,并且在清除设备内存后仍然崩溃,则不太可能是内存问题。尽管每个设备的总内存是已知的,但实际可用内存 要小得多 。此外,该帖子中显示的内存必须在设备上的所有应用程序之间共享,进一步限制内存的可用性。

我发现即使在一个2GB的设备上,iOS也会关闭使用了大约200-300 MB RAM的应用程序,因为它分配太快了。iOS在决定是否杀死应用程序时考虑到分配的数量和速度。由于 Safari 中的每个选项卡都运行分开,因此可能存在相同的机制。您的网络应用程序可能将大量数据迅速加载到RAM中,以致iOS拒绝执行请求。

我建议重新考虑有关内存使用的假设,并在阅读有关iOS真实内存限制的内容后再次对应用程序进行分析。虽然这可能无法解决问题,但至少可以确认内存是否是问题所在。


不,localStorage、sessionStorage、Indexed Database和cookies都是完全空的(我通过Safari上的远程调试找出了这个问题)。 首次加载时所有资源的总大小为19.5MB。 - MrBooks
1
好的,我已经做了一些研究,不认为Safari会在没有明确告知的情况下保存任何本地内容,因此值得关注的是与IOS的兼容性问题,而不是重新启动时发生了什么。特别是在您最近的更新中,似乎存在与渲染纹理方式的兼容性问题。这应该可以帮助您检查 https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/CreatingContentforSafarioniPhone/CreatingContentforSafarioniPhone.html#//apple_ref/doc/uid/TP40006482-SW1。 - Navillus
@Nicolas 是的,你说得对,我在研究时忘记了它是间歇性的。你能否发布一下你加载纹理的代码,以及你使用的纹理文件?据说在IOS上渲染纹理存在一些已知问题。我想将你的做法与一些可行的示例进行比较。 - Navillus
RenderTargetTextures 是一条错误的轨迹!就像我迄今所遵循的其他线索一样... 我们从场景中移除了 2 个灯光,现在它可以工作了。而且你是对的,我认为我们每帧要求的内存太多了。 但我不明白为什么在 iOS 上几个 uniform 和一个额外的光照计算在着色器中会导致内存过多。我相信编写一个非常复杂的着色器不会崩溃... 无论如何,非常感谢 @Navillus,你的帮助非常宝贵! - MrBooks
不客气,@Nicolas。我一直对IOS的奇怪内存问题很感兴趣。通过挖掘这个问题,我学到了更多。祝你在项目的其余部分好运! - Navillus
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接