Currently I am working on an Air app for iOS and Android. Air 3.5 is targeted.
Performance on iPhone 4 / 4s has been acceptable overall, after a lot of optimising: gpu rendering, StageQuality.LOW, avoiding vectors as much as possible etc. I really put a lot of effort in boosting performance.
Still, every once in a while, the app becomes very slow. There is no precise point in time or action or combination of actions after which this occurs. Sometimes, it doesn't occur for days. But when it occurs, only killing the app and launching it again helps, because the app stays slow after that. So I am not talking about minor hiccups that
The problem occurs only on (some) iPhones 4 and 4s. Not on iPad 3,4, iPhone 5, any Android device...
Has anyone had similar experiences and pointers as to where a solution might be found?
What happens when gpu memory fills up? Or device memory? Could this be involved?
Please don't expect Adobe Air to have performance as Native Apps. I am developing App with Adobe Air as well.
By the sound of your development experience. I think it's to do with memory issue, because the performance is not too bad at the begging stage, but it gets bad overtime (so u have to kill the app). I suggest you looking into memory leaking issue.
Hopefully my experience can help you.
I had a similar problem where sometime during gameplay the framerate would drop from 30fps to an unrecoverable 12fps. At first I thought I was running out of GPU memory and it was falling back on rendering with CPU.
Using Adobe Scout I found that when this occurred, the rendering time was ridiculousness high.
Updating to Air 3.8, I fixed the problem by limiting the amount of bitmaps that were being rendered and in memory at once. I would only create new instances of backgrounds for appropriate levels, and then flagging them for garbage collection when the level ended, waiting a few seconds and then moving to the next level.
What might solve your problem is if you reduce the amount of textures you have in memory at one time, only showing the ones you need to. If you want to swap out active textures for new ones, set all the objects with that texture data to null:
testMovieClip = null;
and remove all listeners from it so that garbage collection will pick it up.
Next, you can force garbage collection with AIR:
System.gc();
Instantiate the new texture you want to render a few frames after calling gc. Monitor resources with Scout and the iOS companion app to confirm that it's working.
You could also try to detect when the framerate drops, and set some objects to null then force garbage collection. In my case, if I moved my game to an empty frame for a few seconds with garbage collection, the framerate would recover and the game would resume rendering with GPU.
Hope this helps!
Related
I am curious to know what sort of performance I can expect from Air on iOS. I have a class which creates 30 display objects each with several text fields and a fill.
Each display object takes about 0.011 seconds to create on my PC. This raises to 0.056 on an iPad Retina (A7).
From my debugging it takes around 0.004 to create and format a textfield.
When I get to 30 display objects the 0.056 becomes 1.68 seconds.
Is this typical?
Can anything be done ?
I have traced each and every stage of the class and every function is taking about the same time to execute, so I do not think one specific stage has an issue.
Welcome to the world of mobile devices. They all have a very low (if you compare to that of desktop PCs) CPU power, while Flash uses CPU to render its content normally.
the larger area you need to redraw on the screen - the worse performance is
the more objects are there to draw - the worse performance is
Shapes, strokes, fills, fonts - they all are vector data that Flash need to render and draw, thus they all take a heavy toll on CPU usage, which also results in heavy battery drain. That's why Apple discontinued supporting Flash Plugin on their devices long ago.
Then Adobe announced Stage3D which allows (with a certain dose of work) to take advantage of GPU-rendering, which is faster even on desktop computers, and literally saves the day for Flash/AIR application on mobile devices.
Long story short, slow performance is the way things are for native Flash content. If you want better performance and faster applications on mobile devices, you need to proceed with some GPU-enabled framework, like Gamua Starling.
I'm almost finishing my iOS game written in Swift + SpriteKit.
It's a quite simple game, 30-32 nodes at max. Only 1 thing has physics. The rest is a few animated clouds (around 6). The CPU usage is around 2-3% and max RAM usage of 75-80MB.
Including that I also get frame drops when changing from one scene to another. Why that could be?
(I'm pre-loading all the textures and sounds during game init, and not on the scenes)
When I use the simulator for 5S up to 6S Plus, I don't see any frame drop in there. So that's weird. Looks like it's not my game but my iPhone 6S?
Now, I do also have other games installed on the same device from different developers, and I frequently get random frame drops too. Lags for 2-3 seconds and then comes back to 60fps.
Does anyone know if this is something that's happening after an X iOS update ? or I was even thinking this my be some kind of background service running that's killing my phone. Call it facebook, whatsapp, messenger, etc.
Is there any way I could possibly check on what's going on?
Was this caused by the way that newer versions of SpriteKit are defaulting to Metal render mode as compared to OpenGL mode? For example, do your problems go away when PrefersOpenGL=YES is added to Info.plist? I covered a bit of this performance issue in my blog post about a SpriteKit repeat shader. Note that you should only be testing on an actual iOS device, not the simulator.
I'm not sure what can be done about this. My app is an iPad app and I use about 300MB of ram. There are about 250MB of textures loaded for the game at any given time.
Here is the problem. When I sleep my iPad, if I sleep it for a few minutes and return to my game, it becomes playable again in seconds. If I leave my iPad sleeping after having played my game or while my game is still running for about 1 day then I go back, my game takes about 3.5 minutes to restore. It's not a bug, I've looked through the debugger many times and everything works as expected. iOS must be restoring the heap from somewhere which takes about 10 times longer than loading the game in from scratch.
My current solution is to forget about restoring and I intentionally crash my app so it restarts itself after it has been away which gets me to the same state about 10 times faster. But I don't like this solution.
Has anyone else experienced such issues? Are there api's I should be calling or something to lower the restore times after several hours of iPad sleeping? Is this issue documented anywhere?
My current solution is to forget about restoring and I intentionally
crash my app so it restarts itself after it has been away which gets
me to the same state about 10 times faster. But I don't like this
solution.
This is a guaranteed way to make sure that your app doesn't get approved for distribution on the App Store. There's two solutions to this problem:
1) Redesign your game. There's various techniques to this, including:
Breaking down levels into smaller pieces, so each stage requires less assets to load.
Shrinking textures and assets. E.g., use 256x256 textures instead of 512x512. One 512x512 texture takes up the space of four 256x256 textures. Would you rather load four of your textures in a scene in a few seconds, or 1?
Compress your textures. Compressed textures are smaller and quicker to load than their uncompressed bretheren.
Your application won't even run on an original iPad Mini, because of it's RAM - it has 512MB, and you're currently trying to use 300MB at any given time.
2) Disable your app from staying in the background.
Every time your app loses focus (besides lock screen being toggled), it'll force itself to be reloaded from scratch... much like you're already doing now with a forced crash. See:
If you never want your app to enter the background set the
UIApplicationExitsOnSuspend key in your application’s Info.plist file
to YES
How to exit app while enter background
Those are my suggestions, though in all honesty I'd do the first one if at all possible. It's more work, but you'd be able to make a more courteous iOS application when it comes to memory management plus you'd be able to target more devices.
Been trying to find this bug for days now with no solution. Developing a ios game uising swift and only UIKit. My app displays a lot of small images (about 70 a time). Some uianimations are running repeatingly. After a while my app show some performance lags (tested on a device). Xcode shows only 30MB of memory usage and about 97% CPU time used. Using instruments didnt really help (im not using a lot of memory anyway). How can I track this bug down, this seems so weird to me.
The problem is that using UIKit for such graphics is not the best solution, as it is working through CPU, not GPU. And this is the reason, why application is lagging.
The other reason for it to show only 30MB of memory used, as it does not show memory used for uncompressed images. When you display image on the screen, or use UIViews with drawRect:, it takes really a lot of memory.
We have a memory-intensive 3D app which is primarily targeted at iPad 2 and iPhone 4S, but it works on iPod Touch 4G and iPhone 3GS as well. We have found that the smaller memory footprint on the iPod Touch 4G, combined with the retina display, makes this platform more susceptible to out-of-memory errors. iOS5 also seems to have lowered the available memory somewhat.
It's relatively easy for us to lower the resolution of 3D models, based on the platform we're using, but we have to set that resolution before loading, and thus we cannot effectively lower it dynamically based on memory pressure warnings from the O/S.
We've tuned the memory usage based on trial and error, but we've found that devices that haven't been rebooted in a long time (e.g., months) have a lot less useable memory than devices which have been rebooted recently. (Even if you kill off all the running apps.)
I'm wondering what other iOS app developers use as their practical memory limit for iPod Touch 4G apps?
While keeping all the caveats that everyone is offering in mind, my personal general rule of thumb has been that in sensible weather you can expect to have around the following:
512MB device -> 200MB usable (iPhone 4-4S, iPad 2)
256MB device -> 100MB usable (iPhone 3GS, iPad, iPod Touch 3G-4G)
128MB device -> 50MB usable (iPhone 3G, iPod Touch 1G-2G)
And if you want to rigorously withstand insensible weather without otherwise making a point of being flexibly responsive with memory usage, you can halve those numbers, or even third them. But it will be fairly difficult to guarantee sterling reliability if you can't throw anything overboard when conditions become dire. It's more like a sliding scale of how much performance you're willing to throw away for how much reliability at that point.
In environment predictability terms, iOS is a lot more like the PC than a dedicated machine, for better and worse, with the added bonus of a drill sergeant for an OS.
Recently I found this awesome tool to find what is the maximum memory capacity of any iOS device. We can also find at which memory level we received the Low Memory warning.
here is the link: https://github.com/Split82/iOSMemoryBudgetTest
It's hard to give an actual number because of all the external allocations the OS does on your behalf in UIKit and OpenGL. I try to keep my own allocations to around 30MB, with 50MB sort of my top end. I've pushed it as high as 90MB, but I got jettisoned a lot at that level so it's probably a bad idea unless the task using all that memory is very brief.
If you need to hack around your current problem you could just detect the problematic devices up front and turn down your graphics engine's resolution at startup. You can get exact device info or you could check for display scaling (retina) combined with number of processor cores and amount of RAM to determine what quality level to use.
I've had great success reducing my memory usage by using mapped files in place of loading data into RAM and you may want to give that a try if you have any large data allocations.
Also watch out for views/controls leaking from UIKit as they consume a lot of memory and can lead to being jettisoned at seemingly random times. I had some code which leaked child views from several view controllers. Eventually those leaks would chew up my app, though my app's memory usage didn't reflect the problem directly.