I am new in game development and want to develop a phone game. I am trying to make a complex animation in libgdx, which consists of nearly 300 images (655 × 1160 each, together in size of 42MB). Is there a limit in how big textureAtlas image can be or how many pictures it takes? Will there be a problem if I render 7 animations at once, while 2 of them are as complex as this one (activated skill), but others are just simple character movements?
The atlas can be as big as you have RAM for. The more RAM you have, the bigger atlases you can load.
On Android, you may have problems loading 42 MB big images as it's a lot of allocation at once. There have been multiple posts on Stack Overflow about just that problem. You just have to try loading it and see what happens. If the game crashes with an OutOfMemoryException, you have to make it smaller.
Because Android is a platform with a lot of variation in hardware (some devices have 512 MB total ram while others have 6 GB) there's no "hard limit" to what you can load in on a platform basis. It depends on what device and how much RAM is available (free RAM)Disclaimer: this answer is old and doesn't represent a realistic RAM distribution anymore. With certain phones having as much as 16 gigs of RAM and most flagships boasting at least 4 GB, 42 MB shouldn't (realistically) be a problem anymore. Android RAM allocation is still one of the weirdest systems in existence, and sufficiently large bitmaps may throw an exception separately. Bitmaps in this case do mean through the Bitmap class in "regular" android, and not directly OpenGL and/or LibGDX.
What the TextureAtlas actually contains (complex animations of 30 images vs 2 massive images) doesn't matter. As long as you load it (and manage to get it into memory without the game crashing) there's not going to be a problem rendering it. The framerate may drop though (depending on hardware and how much you actually render) but unless you render thousands of images at once it shouldn't be a problem
Adding android:largeHeap="true" in the manifest is also helpful.
Related
I have an Android app with several activities and within those activities are around 16 diagrams (JPEGs approx 1200px x 800px, around 300kb each). There are a maximum of 3 diagrams per activity.
I am using BitmapFactory to load the images and scale them accordingly and it's all working fine on devices of all sizes (including devices with small memory).
My question is, I am wanting to add more activities, and another 16 diagrams (again, no more than 3 per activity). Will this make a difference to the memory management for my app? I realise my overall app install size will be larger, but in terms of the amount of RAM the app uses, will it stay the same?
My thinking is that the RAM only loads the diagrams in the activity that is currently being viewed so really it's only 3 that are being loaded at once? So in theory would another 16 images make a difference to my app performance?
Thanks!
The amount of RAM usage will increase with the increase of number of processes and images in the activity. You can monitor use application and each activity using android monitor which may highlight the RAM usage for your application w.r.t activities.
I created a second version of my app with 50% less activities and diagrams and tested this and the average RAM was about the same so this pretty much answers my own question, that the RAM use would not increase by increasing the activities and number of images.
Guess what, another Android-Bitmap-OOM question!
Background
Whilst stress testing our application it has been noted that it is possible to max-out the app's process memory allocation after sustained, heavy usage (monkey runner like) with OutOfMemory exceptions being recorded within the ensuing stacktrace. The app downloads images (around 3 at a time) when a page under a ViewPager is selected. There can be 280+ images available for download when the length and breath of the app is exercised. The application uses Picasso by Square for it's image downloading abstraction. Notably, at no point in our application's code are we manipulating Bitmaps directly...we trust that the very talented Square Inc. employees are doing it better than we can.
Here is a picture
The below plot shows the heap allocations over time recorded under the dalvikvm-heap log message. The red dots indicates a user bringing a fresh set of articles into the application in order to bolster the amount of work outstanding and stress the app...
DALVIKVM heap allocations http://snag.gy/FgsiN.jpg
Figure 1: Nexus One heap allocations; OOMs occur at 80MB+
Investigation to-date
Against a Nexus S, Nexus 4, Wildfire, HTC Incredible and a myriad of further test devices, anecdotal testing has shown the memory management to be sufficient with the DVM GC 'keeping up' with the heavy lifting work being completed by the app. However, on high end devices such as the Galaxy S II, III, IV and HTC One the OOM are prevalent. In fact given enough work to do, I would imagine all of our devices would eventually exhibit the failure.
The question
There is clearly a relationship between screen density (our requested image sizes are based off the size of the ImageView), the process memory allocation and the number of images at a given size that would result in the app exceeding it's heap limits. I am about to embark on quantifying this relationship but would like the SO community to cast their eyes over this problem and (a) agree or disagree that the relationship is worth making and (b) provide literature indicating how best to draw up this relationship.
It is important to note that if we destroy the image quality our OOM all disappear but alas the UX is poorer which is why we are wanting to be dicing with the most effective use of the available heap.
Side note: Here is the portion of code responsible for loading these images into the views that have been laid out;
picassoInstance.load(entry.getKey())
.resize(imageView.getMeasuredWidth(),
imageView.getMeasuredHeight())
.centerCrop()
.into(imageView);
The 'dashing of image quality' mentioned above is simply dividing the imageView.getMeasured... by a number like '4'.
First you need to manage the memories allocation ,its a big issue in android as bitmaps takes lots of memories ,for that memory allocation can be reduce by following ways
put all those images which are huge in size to assets folder instead of putting them in drawabable folder . because drawable resources takes memory for caching them .if you load from asset folder the image will not cache .and will takes less memory .
study Lrucache which use for efficient memory management .
put resources in tiny formats for that check TinyPNG
if your images are too large in resolution , then try to use SVG files for images and load SVG file instead of image . check this SVG FOR ANDROID
finally i am not very good in English hope it may helps you.
This post is a little old but I also had this issue recently. Maybe this will help someone else.
General Overview of this massive thread/What helped me.
-Make sure you are using a Singleton Instance of Picasso
-Use fit()
-For large Images or many Images or when used in a FragmentPager/StatePager you should probably use skipmemorycache() and/or largeHeap declaration
Read the thread for more tips. At the time this question was posted nobody had posted this issue on picassos github.
https://github.com/square/picasso/issues/305
I have developed an Augmented Relity app for iOS in Unity. It has a good performance.
The app has several scenes but one of them is much much larger than the others (about 60 targets).
The app size in iOS (uncompressed) is massive (1.9Gb) becouse it has a lot of media (images, videos, textures and 3D content).
Now I'm switching the platform to Android and I'm having a lot of trouble:
-The loading time to the principal scene is very very high (10 or more minutes) rather than 20 seconds in iOS (iPhone 4).
-The textures of the 3D content turns in black.
Is there a limitation size for a scene in Android?
Maximum memory available on android might differ per device.
Most only have 256 MB of memory available for a single application.
As for texture memory (again different per device), you might want to look at the compression used. Using the android standard ETC Unity page on Android should improve loading times. Removing Mip Maps would lower memory use and loading but also potentially decrease FPS (depending on wethere they are used or not).
With Android there is also the option to profile through ADB connection within the Unity Profiler, which could help with narrowing down to a more exact cause of the problem.
Like the title says, should I still be designing my application around a 16 MB heap size limit? The reason I ask is that I've been developing a game recently that runs fine on my nearly 2 year old Droid 2. But when I test my app using an AVD with a 16 MB heap size limit, I get out of memory errors. Monitoring my application with DDMS shows that the total memory allocated for my game is around 20 MB. It isn't a huge difference, but getting my game to work under that 16 MB limit would really hurt the visuals.
Now, if this was 2008, I wouldn't even be asking this question. But it's 2012, nearly 4 years after the G1 debuted. Is it safe to say that most phones made in the past year allow applications to allocate more than 16 MB of memory? Or am I really screwing myself by not designing my application with a 16 MB limit in mind?
The heap limit varies depending on the device resolution (and probably also other factors). So on a high resolution device the heap limit may be 30MB while on a low resolution G1 it is 16MB. Generally you should change your graphics accordingly so low resolution devices uses low resolution graphics (which takes up less space) and high resolution devices uses high resolution graphics (which takes up more space).
Yes we still need it but not in every case.
If you are using native code then memory allocated by c compiler does not include in this limit.So you can provide more memory to your application essential component.
and second way is to using Texture to draw images using OpenGL.then memory for these Texture does not include from limited memory.
But these technique can not be implement in every case
One more important thing , you can not use these 30 MB completely also.Only 30 % of it is usable for one application .
I am making a game which has to load all bitmaps at start because in the in-built game editor the user can put any of the sprites into the level. Also levels use various sprites without any system which would allow to load groups of sprites dynamically for each level.
After a while the are now already 250+ png images in the game with total size of 3.5MB.
The game loads most sprites (about 200) using BitmapFactory.decodeStream without any options set, and also there are about 50 other which are referenced in xml layouts of activities.
When I test on various devices, the game sometimes runs out of memory, but i can't find a pattern and even decide by HOW MUCH i have to, e.g. reduce the size of images or their number.
The phone on which i developed, HTC desire with Android 2.2 24MB VM heap size never runs OOM.
Dell Streak with Android 2.2 and 40MB VM heap size never runs OOM, too.
Motorola Milestone with Android 2.1 and 24MB VM heap size successfully loads all sprites but chokes on the few last images used in ImageView's when starting one of the activities (start menu). If I comment a few of such ImageViews out, it loads ok, but may choke on one of the other activities later. It's also not stable, probably because fragmentation happens differently in different launches.
HTC hero with 2.2 of my buddy (dunno the heap size, is it 16MB?) crashes as well.
What's most confusing is that Motorola has 24MB, the same as HTC desire. Is 2.1 implementing memory management less efficiently? (e.g. leads to more fragmentation?) Or is memory management worse by all Motorola phones? Then why does HTC hero with 2.2 crash? What's bigger in HTC desire than HTC hero?
Looks like OOM happens on older phones, but that's the only thing I've figured out so far.
If OOM only happens on older phones which are, say, 5% of the market, I can just exclude 2.1 or a more specific list from the supported devices by just gathering crash reports and excluding all that crashed from the list of supported. Otherwise I'd now need to scale down all my images by some constant factor (e.g. 1.6), which would mean resizing all the 45 levels which took days and days of designing and testing, repositioning GUI elements etc. Even after that, I'd still not be sure, on which devices the reduction of total size of bitmaps by a factor of e.g. 2 is enough to avoid OOMs.
Any advice on this?
Should I set any specific options for BitmapFactory? btw, most images have transparent bg pixels which, as far as i understand, doesn't allow getting them in 565 format.
I spent 2 days browsing here and in other places but am still at a loss.
Thank you.
I've had to deal with a simpler version of your problem - we had 3 2Mpix layers on top of each other, which, unsurprisingly, sometimes caused OOM.
In my case, instead of using 3 ImageViews on top of each other, keeping all 6 MPix in memory at all times, I manually blended the layers, thus keeping at most 4 Mpix in memory at any one time (and only 2 MPix at "rest" - the layers changed in our application).
This is a classic time-space trade-off - sacrifice efficiency (time) to gain memory (space). It was somewhat slow because you had to recycle() each Bitmap after you were done with it to ensure the memory was freed.
As for the inconsistent OOMs, it probably has to do with garbage collection. You can assume that the garbage collector is non-deterministic and thus any memory pressure becomes non-deterministic as well (depending on when the GC last kicked in).
The short summary is, you have to be very, very careful with your memory usage and there's no way around it. *
* In theory, you could allocate memory outside the Dalvik heap by using the NDK and allocating straight from the OS. It's a huge hack and the bridge between Dalvik and your allocator will be rather ugly.
First you need to find what exactly is using all of your memory. Check this out. Maybe you could be recycling bitmaps, for instance.