3

SHORT QUESTION

I have a bug that only disappears when I restart my device. I would like to know what is released when restarting an iOS device in order to have an idea about what my bug is. Releasing my cache and my RAM don't help to fix my bug, so I wonder what else could be released that fix my bug for a short time.

CONTEXT

I have a web app using WebGL and BabylonJS. It works really fine on all devices and all browsers except on iOS. With Safari, I always end by having the error message "A problem occurred with this web page so it was reloaded".

It happened on an iPad Air 2 (2Go RAM) running iOS 10.3.3 but I saw the same bug on every iOS device I could have in my hands. That's why I consider it as iOS only related. I'm aware about iOS resource limits : https://stackoverflow.com/a/22193143/5053300

I tried to debug this for months, the bug appears randomly, sometimes quickly, sometimes slowly. There's nothing consistent so it's totally impossible to debug.

The best guess is that it's a memory issue because crashs seem to appear faster each time. And because the error message is quite always linked to memory issues.

I suspect textures and renderTargetTextures to take more and more memory (but I don't understand why it wouldn't be released, I don't keep useless references).

But there's something I'm sure : when I restart my device, it always work the first time (until I reload once, then begins the downward spiral).

If I clean my cache (via settings -> Safari) and my RAM (pressing home button when we are in shut down screen), the bug is still here. But if I restart my device, it disappears. Something in memory is released and I would like to know what.

But I also could be totally wrong and it could be something else than memory, I'm open to all your suggestions.

Thanks in advance, it drives me crazy for months !

UPDATE

This is what JS Heap looks like :

JS Heap

UPDATE 2

A scene asking for 90 renderTargetTextures (379x890) each frame does work on iOS. My app does work if I don't ask for any renderTargetTextures. But it crashes more or less quickly if I only ask for one small renderTargetTexture each frame. What conclusions can I get from this observation ? Does it corroborate or deny the idea of a memory issue ?

UPDATE 3

There's no clue the following code really is the cause of the issue, but commenting/uncommenting it generaly makes disappear/appear the bug.

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;
}

I may insist on the fact that this code works in the link posted in update 2 so I don't think this code is relevant. The only thing is, commenting this part of the app seems to remove the random bug. This code asks the 3D engine to render into one intermediary texture before to render to the screen. So this code impacts each frame. In the link, I ask the engine to render into textures 90 times before to render to the screen.

UPDATE 4: PROBLEM SOLVED

The issue didn't depend on what is released on iOS restart, so I can't answer to my own question. But I can say that iOS doesn't like dynamic lighting. From now on, all our projects will be limited to one light on iOS devices.

More lights, more computations each frame. It's too much for iOS that kills apps that ask for too much memory in a short time.

MrBooks
  • 85
  • 10
  • 1
    Please show some code in order to easily investigate the issue. – Tamás Sengel Sep 01 '17 at 16:13
  • It's impossible to isolate the bug, it appears randomly. And code is too huge. That's why I don't ask anybody to fix my bug, because I can't show any relevant code. Sorry. Since it's a WebGL app, there are textures generated and released at each frame. That could explain why a memory issue appears randomly and not always at the same moment. – MrBooks Sep 01 '17 at 16:19
  • only help, try to user profiles if possible & get memory leak. – Gagan_iOS Sep 01 '17 at 17:04
  • I see this error often when browsing regular website likes macrumors.com. – meaning-matters Sep 01 '17 at 17:48
  • When profiling, everything seems to be OK to me. Memory increases until next GC and so on... And it never reaches the iOS resource limits. Other 3D web apps that work fine give me the same type of results. – MrBooks Sep 04 '17 at 09:14
  • Please check https://stackoverflow.com/questions/39495679/ipad-html-web-page-issue – Vini App Sep 07 '17 at 21:21

1 Answers1

3

Without seeing your code I cannot guarantee any solution but I can offer some information about memory issues.

If you are sure that it never crashes on the first load, and it still crashes after clearing your device's memory, then it is unlikely to be a memory issue. That being said, if you are not sure of this, I would suggesting reading more about IOS memory usage. While the total memory for each device is known, the actual usable memory is much smaller. Furthermore, the memory shown in that post must be shared among all apps on the device, further limiting the memory availability.

I have found that even on a 2GB device, IOS will kill an app using ~200-300 MB of RAM because it was allocated too quickly. IOS takes both the amount and the speed of allocations into account when deciding whether or not to kill an app. Since each tab in Safari runs separately, it is likely that the same mechanism is at work. It is possible that your web app loads so much data into RAM so quickly that IOS refuses to carry out the request.

I would recommend reconsidering your assumptions about memory usage and profiling the app again after reading about the true memory limits of IOS. While it may not solve the issue, it will at least confirm whether memory is the issue.

Navillus
  • 307
  • 1
  • 9
  • Thanks ! Yes it never crashes on the first load. And you're probably right that it could not be a memory issue. And that's exactly what I'm looking for : what else could it be, what else does a restart impact ? This [simple 3D scene](https://www.babylonjs-playground.com/#H4PMHG#15) works fine on iPad, even though it asks for 90 renderTargetTextures (379x890 size) each frame ! When I cut my app and only ask for one small renderTargetTexture each frame, it crashes in my app. So it must be something else than memory (but if I don't ask for any renderTargetTexture, it works, so I'm lost haha). – MrBooks Sep 06 '17 at 09:39
  • This is outside my expertise unfortunately, but if it happens after a restart, it sounds like something must be stored locally on the device. Do you ever use Safari's localStorage feature? Also for completion's sake, how much memory does your app use on the first load? – Navillus Sep 06 '17 at 14:48
  • No, localStorage, sessionStorage, Indexed Database & cookies are totally empty (I figure this out with remote debugging on Safari). Total size of all resources loaded at first load : 19.5MB – MrBooks Sep 06 '17 at 15:22
  • 1
    Ok, I have done some research and don't believe Safari saves anything locally unless you explicitly tell it to, so it might be worth looking at compatibility issues with IOS rather than what happens on a restart. Especially with your recent update, a compatibility issue with the way you are rendering textures seems likely. This should help you check that https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/CreatingContentforSafarioniPhone/CreatingContentforSafarioniPhone.html#//apple_ref/doc/uid/TP40006482-SW1. – Navillus Sep 06 '17 at 15:44
  • Shouldn't a compatibility issue crash immediately and not randomly as it seems to happen ? But thanks, I take all possibilities into account. – MrBooks Sep 06 '17 at 16:30
  • @Nicolas Yes you're right, I forgot it was intermittent while researching. Could you post your code where you load the textures, and maybe the texture file you are using? There are supposedly some known issues with rendering textures on IOS. I would like to compare what you are doing with some working examples. – Navillus Sep 06 '17 at 16:37
  • I've updated the question. No texture files: renderTargetTextures are generated each frame. I know that iOS has texture size limits (so I downsample textures before generating them) and isn't often compatible with floating type textures. I don't know much more. – MrBooks Sep 06 '17 at 17:25
  • Thinking about it again, if a simple scene rendering a lot of textures works, but your (complex) project rendering a single texture fails, maybe something else in your app is already pushing memory limits, and the sudden memory block required by the textures pushes IOS to fail to load your project. What other memory intensive actions are you doing? It looks like your project allocates up to 70MB in a fairly short time period. Could you attempt to decrease your memory usage from other sources and see what affect that has? – Navillus Sep 06 '17 at 17:50
  • I totally agree. Loading textures and importing 3D models a tthe beginning. Textures are light and 3D models are optimized but the project is huge so it still takes a lot of memory. I tried to come back to an old commit of the project, where there's almost nothing (a few textures and really basic meshes), and it still crashes. – MrBooks Sep 06 '17 at 18:05
  • Just to clarify, you went to a version of the project that uses less memory and it still crashes? – Navillus Sep 06 '17 at 18:06
  • Your current project seems to have larger spikes of up to 30mb in a few seconds. I have personally tested that IOS is willing to kill apps for this type of memory usage (and in fact does so more often than not for smaller amounts). This answer suggests that you try lazy loading your resources as you need them rather than all at the start. https://stackoverflow.com/a/5887783/8545002 – Navillus Sep 06 '17 at 18:21
  • Yes, I went to an old version of the project and it still crashes. I should post the profile. I really hope that it's juste a matter of allocating memory too fast, I'll investigate. Customer doesn't want lazy loading but if there's no choice with iOS (and if it solves the problem of course), I'll do it, thanks ! – MrBooks Sep 07 '17 at 09:25
  • No problem. Good luck checking that out, and if you find anything informative be sure to update this post. – Navillus Sep 07 '17 at 14:39
  • RenderTargetTextures were a wrong track ! As every other leads I followed so far... We removed 2 lights from our scene, and it works. And you're right, I think we asked for too much memory each frame. But I don't understand how are a few uniforms and an additional lighting computation in a shader too much for iOS. I'm sure that writing a very complex shader won't crash... Anyway, THANK YOU A LOT @Navillus, your help was precious ! – MrBooks Sep 08 '17 at 16:14
  • You're welcome @Nicolas. I've always been interested in IOS's weird memory quirks. I learned quite a bit more by digging through this. Good luck with the rest of your project! – Navillus Sep 08 '17 at 16:27