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.
Related
As I researched, Android allocates limit memory for each process, maybe range from 16MB to 24MB for each one. Here is reference
Nevertheless when I view memory usage for one application in setting, I often see one normal application costs hundred megabytes for memory (on one process). There is a conflict here that I cannot understand.
Thanks :)
NDK code can use more system RAM than can a single Dalvik/ART process. Also, the app might be using more than one process, or it might be using android:largeHeap to request an above-normal heap size.
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.
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.
On android.com they say, that if you're working in Java, the maximum memory you can use is 16 MB. At least that's the one the devices are supposed to support. If you have an older phone, you'll notice that you can't get more, you get an OutOfMemoryError instead. Not if you're doing the same thing using the NDK. In on of my applications I am trying to get 50MB and more, and so far Android was fine with that.
I havn't found anything related to that on android.com.
Is there any limit like in Java, too?
If yes: what's the limit?
If no: What is a good value for that?
Problem is, that I have to build my code depending on that size.
[Edit:]
I tried what Seva Alekseyev were suggesting.
root#android:/ # ulimit -a
ulimit -a
time(cpu-seconds) unlimited
file(blocks) unlimited
coredump(blocks) 0
data(KiB) unlimited
stack(KiB) 8192
lockedmem(KiB) 64
nofiles(descriptors) 1024
processes 7806
flocks unlimited
sigpending 7806
msgqueue(bytes) 819200
maxnice 40
maxrtprio 0
resident-set(KiB) unlimited
address-space(KiB) unlimited
root#android:/ # ulimit -v
ulimit -v
unlimited
root#android:/ #
The memory I am requesting (by using "alloc" or "new") is virtual memory (ulimit -v). So there's no chance to figure out how much I can gain?!
You're subject to three types of memory limits:
1) Artificial limits put in place to keep the system responsive when multitasking -- the VM heap limitation is the main example of this. ulimit is a potential mechanism for a the OS to provide further limitations on you, but I have not seen it being used restrictively on Android devices.
2) Physical limits based on available real memory. You should have a baseline device you're developing/testing on, and should be pretty aggressive in assume other processes (background services, other apps) need memory too. Also remember that memory in use by the OS varies with OS version (and will tend to increase over time). Stock Android doesn't swap, so if you go too far you're dead. One potential scenario is a Nexus One (512MB RAM) with an audio player and the phone app going in the background, and a "balloon" service eating another 100MB physical memory to give some leeway; in this configuration you'll still find more than 100MB available.
3) Virtual memory limits based on address space. Stock android allows overcommitment of memory, so it won't blink if you ask for a 1GB virtual allocation (via mmap, etc) on a device with 512MB of RAM, and this is often a very useful thing to do. However, when you then touch the memory, it needs to be brought into physical memory. If there are read-only pages in physical memory they can be ejected, but soon enough you're going to run out, and without swap -- dead. (The combination and overcommit and no swap leads directly to process death in out-of-memory situations, rather than recoverable errors like malloc returning null).
Finally, it's worth noting that whether calloc/malloc/new require physical allocation is allocator-dependent, but it's safer to assume yes, especially for allocations less than a large number of pages. So: If you're dealing with < 100 MB of standard, well behaved allocations, you're probably in the clear -- but test! If you're dealing with large amounts of data that you'd like memory mapped, mmap is your friend, when used carefully, and is your best friend when used with PROT_READ only. And if you're dealing with > 100 MB of physical memory allocations, expect to run quite nicely on modern devices, but you'll have to define a baseline carefully and test, test, test, since detecting out-of-memory situations on the fly is not generally possible.
One more note: APP_CMD_LOW_MEMORY exists, and is a great place to purge caches, but there's no guarantee it's called in time to save your life. It doesn't change the overall picture at all.
If I have understood correctly, an android process has two heaps - one managed by the VM and one native.
The size of the VM heap cannot exceed 16mb (at least, this value can be higher on some phones).
But what about the maximum size of the native heap?
The 16 mb limit doesn't seem to be a hard limit in that an app can allocate more than 16mb through the NDK, but the OS will start killing other processes and possibly the foreground process as well when a high amount of memory is used.
When does the OS start behaving this way? When the native heap + VM heap size exceeds 16mb?
Debug.getNativeHeapSize() gives the size of the native heap, but is there a function to check the combined native + VM heap size?
Curious to hear from someone who knows how this works!
There is no "line of death" in Android memory management. When the system needs to kill processes to reclaim memory, it considers a number of different factors, including the process' importance (determined by factors like whether or not it's in the foreground, or providing services to a foreground app) and how much memory it's using.
If your process is idle, and sitting on more memory than anything else, it's likely to be killed first.
The exact algorithm has evolved a bit over time, and the system doesn't make any guarantees about specific behavior.