Good day,
I've quite big project currently localized to 21 languages where one language has around 9000 words! This is not so interesting, but
compiled and started application with all these resources, took after start around 11 MB in memory (simply measured by Debug.getNativeHeapSize())
when I remove 20 languages and keep only default one, it has after start only 7.5 MB
Because biggest problem of my app are devices with low memory available for a single process (mainly older devices with 2.X android), this is very serious question for me.
So here comes two questions, hope that someone will have any useful suggestion
I expect that Android loads only required resources, so how it's possible that these additional languages makes so huge difference, when in memory should be in worst case just list of available resources
if there is not any explanation for point 1., is there any way to precompile resources into separate packages and download them on request? For example in some starting activity where user select language he wants to use?
any suggestions are more then welcome. Thanks
Memory measurement on Android is reminiscent of a portion of Zork: a maze of twisty little passages, all alike.
If your concerns are stuff in the VM, the best way to try to get answers (IMHO) is to use MAT. Particularly on Android 3.0 and higher, if you are allocating memory in the SDK, it should show up here.
For a more thorough discussion of non-MAT ways of measuring memory usage, and their pitfalls, I recommend Dianne Hackborn's epic answer on the subject.
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 9 years ago.
Improve this question
By design, Android apps are very limited in the amount of heap memory they can use. The limitation for SDK apps is as little as 16MB on old devices. This design choice usually makes sense because the OS tries to support multi-tasking on devices which are usually very low on memory - so each task gets its own small ration.
The memory limitation varies per device. On stock Samsung Galaxy S2 for example, each app gets somewhere between 32MB-64MB. This device has 1GB of RAM, so a single task can only use about 5% of what the device can offer.
It's worth to mention that memory strategy on iOS is very different. To the best of my knowledge, there is no externally enforced limit on how much memory an iOS app can use. You can allocate as much as you want until the system runs out of memory. If you're too greedy, other background apps will be terminated.
Let's get this out of the way - this isn't a discussion about which memory strategy is better.
The memory limitation on Android is hard to swallow for certain types of apps. Graphic-intensive apps (such as games) need lots of memory to hold bitmaps. Even a web browser should be pretty hard to implement under the default limit.
When resource optimization isn't enough, the standard strategy for overcoming the memory limit is using the NDK. The "native" heap in Android doesn't have artificial limitations and behaves much like the heap on iOS. Using the "native" heap to hold bitmaps works well - this is actually how bitmaps were kept on Android 2.3.3 and lower (the JVM still limited them artificially though).
I'm looking for an NDK+JNI library to hold unlimited bitmaps in the "native" heap. Its Java interface should be identical to the stock bitmap API. I'm not aware of any public project for this purpose and will appreciate your help to find one. If you've implemented this before and willing to share your code, it will be appreciated as well.
Final comment: Please do not make this a discussion about the morality of having such a library available to the general public.
The heap limit on recent 2GB devices is around 192MB. Apps that need a large amount of memory, such as image editors, can include android:largeHeap=true in the app manifest to increase that to a higher limit (currently around 512MB).
Working around the limits is generally a bad idea. It's calibrated on each device based on the amount of physical memory, the display size, and how the device performs when it has a bunch of apps running. Remember that, on Android, your app isn't the only thing present, and not all of physical memory is reserved exclusively for apps (a big piece goes to the kernel, buffers for multiple frames of graphics and video content, and so on).
The bigger your app is, the more likely it is to be killed. The kernel tries very hard to not kill the foreground app, which means you're going to start squeezing out background processes -- or cause them to do so much paging and restarting that it starts to impact the performance of your game.
Having said all that, I think you're looking for this.
As my app is using a lof of pictures, I get the famous issue of OutOfMemoryError on older devices.
Explanations: http://androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/
According to Android Developers your device has at least 16MB of heap
space (T-Mobile G1) for storing your application data. But as Yekmer
said in Yekmer’s Posterous , images are not stored in the heap space.
The space reserved for images in an Android application is very
small, and having a big application using a lot of images, may easily
lead to the OutOfMemoryError.
My question
Having a lot of code, I would like to know if there is a tool in Android Studio that would help me to track the memory used by images and to know which steps of my code are increasinf the most the memory used.
What I don't need
I know how to get information like ActivityManager.getMemoryInfo() or Runtime.getRuntime().totalMemory() but I guess they won't be usefull, right?
Some ideas
I tried to understand the numbers given by "adb shell dumpsys meminfo", but I don't know if that would be a great start...
Use MAT to diagnose memory leaks and other out-of-memory causes:
Android Developers Blog post
Google I|O conference video
I've spent the last few days trying to remove memory leaks in my game, resulting in many out of memory errors. I'm on the verge of adding a significant amount of graphics, that while not hugely complicated, will add significantly to the processing requirements of my system, and I'm a bit worried about my memory usage, and I was hoping someone might have some tips for me. I don't want to go below Android 2.1, so please tailor any answers to that end.
First of all, my game consists of:
2 activities, 13 XML files (Some relating to a small part of a layout, some dialogs, and 2 directly related to activities.
A number of drawables, made in Adobe Illustrator and converted to PNG. These are probably large, but not unusually large, and for the most part, only small amounts of them are in memory at any given time.
Quite a few dialogs.
Targeted towards Android 1.6 and above.
I used the newest Admob, and as a result, I have to build against 3.2.
My default heap size for my emulators is around 24 MB.
A few sample images from my game:
What I have learned:
Despite my total app size being only around 500K, I somehow am taking up 24 Megs, as calculated by adb shell procrank.
I have done considerable optimization, but am not seeing large increases in memory.
Using tools to find what is in the Heap typically only show around 7 MB avaliable, with around 3 MB being used. Sometimes, when opening new dialogs and the like, I see an increase, but I can't say that I see it being all that large...
MAT shows that none of my classes are using an unusually large amount of memory.
So, given all of this, my questions.
Is 24 Mb an actual requirement to develop to (1.6+ android)?
Assuming it is, how can I both allow for nicer graphics for systems which can handle it, but not crash and burn for older systems?
What are some common gotchas that I can use to improve my memory usage?
Without seeing your actual code, I can't say if the following will be relevant to you or not. However, it is worth a shot.
If you are not already doing so, you can consider using something called an LruCache. http://developer.android.com/reference/android/util/LruCache.html
Using this tool, you can determine at what point your cached objects (such as Bitmaps) will become eligible for garbage collection. So, if you want to set it at 4mb (for example) the OS will deal with it should it try to grow beyond it. (See docs for implementation details and a good example).
The only downside is that that little gem only came along with 3.2, so you would have to make that your min SDK in the AndroidManifest, or do a check programatically at run time for the api level to determine if you can use it. Pre 3.2 I would say you need to call recycle() on any Bitmaps you are using, but if you have optimized already I would think the chances are good you are already doing this.
This is a nice little snippet about the difference between the heap and native memory. http://code-gotcha.blogspot.com/2011/09/android-bitmap-heap.html It may (depending on what you are doing) help you to understand why you are not seeing the drop in memory you are expecting.
And finally this post from SO should help when dealing with heap size as well:
Detect application heap size in Android
Hope that helps.
I am looking for any kind of website, blogpost, wiki, discussion, book, magazine, scientific paper, which on good authority could explain the internals of memory management in Android. I know very well that a big part is Linux and this is where I should go first, but Android has dalvik, which is, as far as I understand, deeply integrated with the Kernel, also, Android is unloading apps if it runs out of memory, which is probably what Linux does not do. So, I am looking for an authoritative answer about memory management in Android. Topics include, but are not limited to:
How to interpret values from adb shell dumpsys meminfo, i.e. what is the meaning of each value: size, alloc, free, Pss, priv dirty, shared dirty, what kind of data is it stored there?
What would be the best metric to evaluate memory consumption on the device?
Where is each *.so loaded to? Or does Android have execution in place implemented?
Are there any limits on how much memory an application can consume?
Does OS assign a contiguous chunk of memory, which can grow as long as it is contiguous, or some kind of fragmentation is permitted?
Etc.
There is a great answer in this thread How do I discover memory usage of my application in Android?, but I want some more in-depth explanation, thus asking for an external resource.
Google IO official Conference about Memory Management: http://www.youtube.com/watch?v=_CruQY55HOk
I am currently writing a paper on the Android platform. After some research, it's clear that Dalvik has room for improvement. I was wondering, what do you think would be the best use of a developer's time with this goal?
JIT compilation seems like the big one, but then i've also heard this would be of limited use on such a low resource machine. Does anyone have a resource or data that backs this up?
Are there any other options that should be considered? Aside from developing a robust native development kit to bypass the VM.
For those who are interested, there is a lecture that has been recorded and put online regarding the Dalvik VM.
Any thoughts welcome, as this question appears subjective i'll clarify that the answer I'll accept must have some justification for proposed changes. Any data to back it up, such as the improvement in the Sun JVM when it was introduced, would be a massive plus.
Better garbage collection: compacting at minimum (to eliminate memory fragmentation problems experienced today), ideally less CPU intensive at doing the collection itself (to reduce the "my game frame rates suck" complaints)
JIT, as you cite
Enough documentation that, when coupled with an NDK, somebody sufficiently crazy could compile Dalvik bytecode to native code for an AOT compilation option
Make it separable from Android itself, such that other projects might experiment with it and community contributions might arrive in greater quantity and at a faster clip
I'm sure I could come up other ideas if you need them.
JIT. The stuff about it not helping is a load of crap. You might be more selective about what code you JIT but having 1/10th the performance of native code is always going to be limiting
Decent GC. Modern generational garbage collectors do not have big stutters.
Better code analysis. There are lot of cases where allocations/frees don't need to be made, locks held, and so on. It allows you to write clean code rather than doing optimizations that the machine is better at
In theory most of the higher level languages (Java, Javascript, python,...) should be within 20% of native code performance for most cases. But it requires the platform vendor to spend 100s+ developer man years. Sun Java is getting good. They have also been working on it for 10 years.
One of the main problems with Dalvik is performance, which is terrible I heard, but one of the things I would like most is the addition of more languages.
The JVM has had community projects getting Python and Ruby running on the platform, and even special languages such as Scala, Groovy and Closure developed for it. It would be nice to see these (and/or others) on the Dalvik platform as well. Sun has been working on the Da Vinci machine as well, a dynamic typing extension of the JVM, which indicates a major shift away from the "one language fits all" philosophy Sun has followed over the last 15 years.