I'm studying about RAM memory, and I see that helloworld from the android samples uses about 13MB of android memory.
How does it happen, if the app have only an activity with a TextView?
And what to do to reduce memory usage? and which uses more memory?
I see that helloworld from the android samples uses about 13MB of android memory
You did not indicate how you are measuring this memory usage.
Please read:
Dianne Hackborn's blog post, "Process Stats: Understanding How Your App Uses RAM"
Dianne's epic StackOverflow answer on measuring memory usage, particularly the first paragraph:
Note that memory usage on modern operating systems like Linux is an extremely complicated and difficult to understand area. In fact the chances of you actually correctly interpreting whatever numbers you get is extremely low
Anything that you use that lies beyond what is written in those posts may or may not be accurate. And even interpreting what Process Stats is telling you is a bit of a challenge.
How does it happen, if the app hase only an activity with a TextView?
It is unlikely that your app has 13MB of consumed heap space. What you are seeing probably includes memory shared with other processes, for the Dalvik VM, platform libraries, and framework classes.
Android developers should be worrying about their heap space, first and foremost. Most of the memory usage beyond that is driven by the platform, not you (notable exception: NDK libraries that you load and the memory that they consume, for code and data).
what to do to reduce memory usage?
Probably nothing, because probably nothing needs to be done.
For more complex apps, as thepoosh mentions in a comment, you can generate a heap dump from DDMS and examine that in MAT to see if your app is leaking memory, resulting in an over-use of heap space.
You are welcome to try using android.os.Debug to try to get a sense of how much the heap is being utilized at runtime.
And, you are welcome to read the documentation on memory usage.
Related
I am trying to understand where my app is using memory, and where I can make it more efficient in this respect.
In the Android Monitor part of Android Studio, I have dumped the Java Heap, and am looking at the generated hprof.
And I see a lot categorized under FinalizerReference:
What is this? How can I understand better what is causing it, and how to keep it down? Looking into the "Instance" panel doesn't help me much... doesn't make much sense.
I have tried looking at this but it's all slightly over my head at the moment.
Also, at the moment the memory monitor is reporting (in the live chart section) an Allocated memory of 10.58 MB. But on my device, in Application Manager > Running Processes, my app is showing a memory usage of 44MB. Why the discrepancy? If it's the ~33MB I want to try and reduce, I'm not apparently even seeing that in Android Studio, so no real hope of identifying what it is?
There may not be much you can do about FinalizerReference memory usage. See this question for more details - basically some objects implement finalize() and these are handled a little differently, such that they can end up sticking around longer. I haven't looked into it too closely, but I suspect that some android sdk objects do this and there's little you can do about it except for maybe tuning up your object caching/recycling to reduce it.
I'm not sure if this would help with FinalizerReference, but one thing I like to do to track down memory leaks is to find suspicious objects' connections to the GC root.
If you're using the Eclipse hprof analyzer (independent of the actual Eclipse IDE; works with hprofs generated by android studio), this is one way to access this:
Overview
Histogram
Right-click, "List Objects"
Right-click an object you suspect is leaking, "Path to GC Roots"
Now you should see a list of nested references leading back down from the gc root to your object.
I'm not exactly sure what is owing to the discrepancy - here is a similar question on that. Apparently the memory monitor tool may only be reporting heap allocations made by Java code, whereas the device reports the entire processes's memory usage.
The Retained Size reported by the Memory Profiler for FinalizerReference is currently a meaningless number, as I argued in my answer to my own similar question.
To summarize: Treating FinalizerReference like any other class when profiling (as Memory Profiler does), leads to repeated counting of the same memory when calculating its Retained Size.
I view this as a bug in Android Studio's Memory Profiler, and have filed this issue.
iOS apps (for the most part) is written in Objective-C, which is a subset of C, and is therefore a data managed language, unlike Android/Java.
In Android, you have the ability to increase heap size by simply adding this one line in the XML android manifest:
<application android:largeHeap="true"/>
Is there an iOS version to doing something like this?
Well in iOS you don't have any control over the memory.
It is all managed by the kernel. So you cannot increase the heap size.
As pointed out in the comments, memory management has a different notion in iOS.
You get as many memory as available but if the app uses to much memory it will be killed by the system.
Now that you explained your goal, you shouldn't download large files into memory, this will cause trouble. Instead you should save it directly to the disk as you get the response.
Take a look at Apple's "Memory Usage Performance Guidelines" for an explanation of how iOS doesn't manage swap space.
Although OS X supports a backing store, iOS does not. In iPhone applications, read-only data that is already on the disk (such as code pages) is simply removed from memory and reloaded from disk as needed. Writable data is never removed from memory by the operating system. Instead, if the amount of free memory drops below a certain threshold, the system asks the running applications to free up memory voluntarily to make room for new data. Applications that fail to free up enough memory are terminated.
iOS attempts to provide each application with as much of the device's memory as the OS can spare. However each application is limited to the device's physical memory. There is no option to allocated larger blocks and expect them to be swapped to disk as needed.
Manipulating the heap size in iOS is therefore not a meaningful concept. Each app already has the largest heap the OS can provide. Instead apps must attempt to minimize their memory footprint to remain within the available space on the host device. This means purging in-memory caches in response to memory warnings, streaming access to resources on disk (as #CouchDeveloper suggested in a comment), and minimizing the amount of memory used overall.
As an additional complication iOS attempts to keep memory in use. Unused memory is wasted capacity and users may be better served by the OS keeping more applications suspended and in memory rather than terminated. As a result attempting to measure available free memory does not give a meaningful result. As the device runs low on free memory other applications will reduce their use in response to memory warnings or by being terminated completely.
The size of the VM heap cannot exceed 16mb, 24mb, 32mb depending on the phone.
But what is the maximum size of the native heap? How much native memory can be allocated to the app when it is in foreground.
Thanks.
Technically there's no restriction in the NDK. Someone asked this a while back and was referred to this android-ndk Groups thread. A relevent quote:
"Also given that this is the NDK list, the limit is actually
not imposed on you, because it is only on the Java heap. There is no limit on
allocations in the native heap..."
Dianne Hackborn
She does go on to say that it shouldn't be abused and if it is than applications could be killed.
There's no simple answer to this; you can use as much memory as the device has, minus what it's using for other programs. When Android thinks it's low on memory, it'll start killing background tasks, so it's a soft limit. Most devices do not have swap space. You can get some statistics about the device's memory from inside Dalvik with android.app.ActivityManager.MemoryInfo (I assume there's an NDK equivalent).
adb shell dumpsys meminfo PACKAGENAME will give you native and dalvik memory usage of your app.
I have an android app that uses alot of memory doing pixel manipulation. And what I have noticed is that android does not kill programs or free memory in favor of the foreground app. And my app just crashes with not enough memory errors. Right now I have it autodetect how much memory is left and scale pictures appropriately. This prevents crashes but results in poor image quality.
Is there a way to tell Android OS, free up memory as my app is memory hungry. From what I read from android, the OS should do this automatically. But it doesn't appear to do it. Maybe I'm missing something? The iPhone seems as it handles this much better.
Android apps have a hard Java heap limit which varies between devices. 24MB is a typical amount.
So the obvious workaround is to not allocate your big objects in Java... you can malloc your pixel byte arrays from a native C method instead.
However 24MB ought to be enough for anybody, to borrow a phrase, so I recommend you try to rethink your approach too. Perhaps be more aggressive about reusing bitmaps from a fixed-size pool, break your images up into smaller tiles, etc etc.
Avoid using getPixel() and setPixel() too much, it hence results in a really really bad performance, it's already mentioned on Android Documentation.
Also, manage your own memory usage Java, Garbage Collector will function as long as you follow the rule.
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