I was rather startled recently to notice that the standard Android
kernel appears to have the memory overcommit setting set to 1. This is
--- as far as I can tell, the numbering got changed not long ago and not
all the documentation has been updated --- these means 'allow all memory
allocations even if no RAM+swap is available'.
The knock on effect of this is that running out of memory will cause
either a memory trap in the application or else the OOM killer will nuke
your entire process without warning.
Can anyone comment on this? I know, for example, that the Android patch
has modified the OOM killer. I would have thought that memory overcommit
should be disabled on this kind of embedded device?
--
┌─── dg@cowlark.com ───── http://www.cowlark.com ─────
│
│ "They laughed at Newton. They laughed at Einstein. Of course, they
│ also laughed at Bozo the Clown." --- Carl Sagan
Hello,
I was rather startled recently to notice that the standard Android
kernel appears to have the memory overcommit setting set to 1. This is
--- as far as I can tell, the numbering got changed not long ago and not
all the documentation has been updated --- these means 'allow all memory
allocations even if no RAM+swap is available'.
The knock on effect of this is that running out of memory will cause
either a memory trap in the application or else the OOM killer will nuke
your entire process without warning.
Can anyone comment on this? I know, for example, that the Android patch
has modified the OOM killer. I would have thought that memory overcommit
should be disabled on this kind of embedded device?
Hello,
I was rather startled recently to notice that the standard Android
kernel appears to have the memory overcommit setting set to 1. This is
--- as far as I can tell, the numbering got changed not long ago and not
all the documentation has been updated --- these means 'allow all memory
allocations even if no RAM+swap is available'.
The knock on effect of this is that running out of memory will cause
either a memory trap in the application or else the OOM killer will nuke
your entire process without warning.
Can anyone comment on this? I know, for example, that the Android patch
has modified the OOM killer. I would have thought that memory overcommit
should be disabled on this kind of embedded device?
Yes, but that doesn't really answer my question --- *why* is memory
overcommit used on Android? It's normally used on systems with huge
amounts of swap to make more efficient use of physical memory, but
Android devices don't have any swap.
The specific problem I've got here is that an app can successfully
allocate memory which it then can't use. Memory overcommit hides memory
allocation failures from the app. The first the app knows that the
memory isn't available is when the OOM killer terminates it without warning!
--
David Given
d...@cowlark.com
Yes, but that doesn't really answer my question --- *why* is memory
overcommit used on Android? It's normally used on systems with huge
amounts of swap to make more efficient use of physical memory, but
Android devices don't have any swap.
The specific problem I've got here is that an app can successfully
allocate memory which it then can't use. Memory overcommit hides memory
allocation failures from the app. The first the app knows that the
memory isn't available is when the OOM killer terminates it without warning!
Dianne Hackborn wrote:
[...]
> If you turn off over-commit, I believe Android won't even boot on a G1,
> because Linux would need to assume that RAM is needed for every mmapped()
> thing, and we run out of it well before the system is fully up.
Not necessarily --- my intuitive understanding would be that overcommit
would only applies to anonymous storage and not to file storage, as
mmapped() files are backed by actual *files* and not by the pool of swap
pages. (Besides, most of those mmapped() files that Android's using are
read-only and their pages can be silently discarded at any point.)
[...]
> Put another way: if you are really using so much memory that the kernel
> needs to kill your app, you are well past the line of being a good citizen
Oh, absolutely. But it would be rather nice to have a medium line
between happy-happy-fun-joy and the boys coming round saying, "'ere, Mr.
Torvalds would like a *word* with you..."
(What we've actually got is a portable API implementation for native
apps. The memory allocation function is defined to return NULL on
allocation failure. It had never occurred to us that *making* it return
NULL on allocation failure could be hard.)
- --
┌─── dg@cowlark.com ───── http://www.cowlark.com ─────
│
│ "People who think they know everything really annoy those of us who
│ know we don't." --- Bjarne Stroustrup
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iD8DBQFKrslpf9E0noFvlzgRAuuOAKCAEARJSEPcHxcrEowsxwcMBvkxGwCcC1Jz
kuny8oLQqn1S8mBDmqp9Bwk=
=iCwo
-----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Dianne Hackborn wrote:
[...]
> If you turn off over-commit, I believe Android won't even boot on a G1,Not necessarily --- my intuitive understanding would be that overcommit
> because Linux would need to assume that RAM is needed for every mmapped()
> thing, and we run out of it well before the system is fully up.
would only applies to anonymous storage and not to file storage, as
mmapped() files are backed by actual *files* and not by the pool of swap
pages. (Besides, most of those mmapped() files that Android's using are
read-only and their pages can be silently discarded at any point.)
(What we've actually got is a portable API implementation for native
apps. The memory allocation function is defined to return NULL on
allocation failure. It had never occurred to us that *making* it return
NULL on allocation failure could be hard.)
David Turner wrote:
[...]
> That can only be said for files that are mapped read-only. It doesn't apply
> for
> anything that is shared copy-on-write (e.g. the Zygote process pages, as
> well
> as initial heap) and non-file mappings.
Ah, I'd forgotten about copy-on-write.
[...]
> But it *is* hard to define what "allocation failure" really means if you
> have
> memory overcommit enabled.
Yes, that's precisely my point!
In fact, I find the OOM killer behaviour deeply suspect. I do not
believe that randomly killing processes is *ever* the right thing to do
on a reliable system, as it completely denies the application the
ability to properly clean up after itself. What happens if the app is in
the middle of a file operation at the time? You lose, that's what. (Not
*everything* can be journalled.)
If I was going to have overcommit enabled, I'd much rather have the
allocation failures exposed to the application in the form of the
appropriate signal when the application fails to access the page. SIGBUS
('bad memory access') would seem to be the suitable one here. That
allows the application to catch it and do any applicable cleanup, and
any application that doesn't care will be killed anyway.
This would also have the advantage that you'd be much more likely to
terminate the offending process; in my experience the OOM killer has a
nasty tendency to home in on the wrong process. Hopefully that's been
fixed in the Android patches.
Incidentally, does Android use rlimits to impose per-process memory limits?
- --
┌─── dg@cowlark.com ───── http://www.cowlark.com ─────
│
│ "People who think they know everything really annoy those of us who
│ know we don't." --- Bjarne Stroustrup
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iD8DBQFKrth5f9E0noFvlzgRAjblAJ44qz7poU+R6hKbmAJTGrO5FwwerwCeKVSb
6ucGqn6l8sWJ8mlanQ8PE5s=
=Y3tU
-----END PGP SIGNATURE-----
In fact, I find the OOM killer behaviour deeply suspect. I do not
believe that randomly killing processes is *ever* the right thing to do
on a reliable system, as it completely denies the application the
ability to properly clean up after itself. What happens if the app is in
the middle of a file operation at the time? You lose, that's what. (Not
*everything* can be journalled.)
If I was going to have overcommit enabled, I'd much rather have the
allocation failures exposed to the application in the form of the
appropriate signal when the application fails to access the page. SIGBUS
('bad memory access') would seem to be the suitable one here. That
allows the application to catch it and do any applicable cleanup, and
any application that doesn't care will be killed anyway.
This would also have the advantage that you'd be much more likely to
terminate the offending process; in my experience the OOM killer has a
nasty tendency to home in on the wrong process. Hopefully that's been
fixed in the Android patches.