Reputation: 728
So one of the challenges on Android is various device specifications (in particular device memory).
I've written my model objects to extensively use Java SoftReferences
in a lazy load fashion, so the VM is free to trim not currently used parts of the data model as it sees fit and they are just reconstituted as needed.
However, one challenge in practice with SoftReferences
is that they tend to be cleared within a few seconds of become weakly referenced as opposed to hanging around until the VM is low on memory, so they work well in terms of allowing the model to trim, but they don't work as well in that it often means nothing is in memory. Ideally on a device with plenty of memory, you'd let the user benefit from keeping objects in memory.
As a result, it's common to combine SoftReferences
with an LRU mechanism, where the LRU keeps a hard pointer to the recently referenced objects. This of course is not ideal since it assumes that you have enough memory for all these hardly referenced objects.
It also makes it a challenge to know what is a good default for the LRU.
In a perfect world, Android would use it's low memory callback as a hint (so I could possibly start with a small LRU, and periodically bump it up until low memory callbacks started occurring then back it off to find a good value for a device), but in my experience this callback never seems to coincide with actual VM memory pressure.
Has anyone come across a reasonable way of detecting that your data model is using too much memory on a particular device?
Upvotes: 11
Views: 1503
Reputation: 694
Here's a more detailed NDK answer:
Looking at the Bionic LibC source for sysconf reveals that _SC_PHYS_PAGES
and _SC_AVPHYS_PAGES
are implemented by reading /proc/meminfo
, which is maintained by the Linux kernel. The first few lines of that file on the Lenovo Android 7.0.1 device with 4GB RAM I'm using look like this:
MemTotal: 3721064 kB
MemFree: 208108 kB
MemAvailable: 2543032 kB
sysconf( _SC_PHYS_PAGES)
gives you the MemTotal
value, in units of the page size. This seems to be the total memory available to Android for code, data, and so on. It's about 300MB less than the claimed physical RAM on the device I'm using, which may be accounted for by the screen buffer and so on. sysconf( _SC_AVPHYS_PAGES)
gives you the MemFree
value, in the same units. This appears to be the memory that isn't in use for anything at all. On my 4GB device, it's only about 200MB. Sadly, there is no sysconf parameter for the far more useful MemAvailable
value, which is the RAM that can be made available if required. Apparently this is because MemAvailable
was only added to the Linux kernel in early 2014, while the sysconf() support seems rather older than that. MemAvailable
is not in a Samsung Android 5.0, but is in Amazon FireOS 5.6 (based on Android 5.1), and a Motorola Android 7.1; I don't know about 6.x.
What I'm planning to do for an NDK test harness (not a app that will be distributed), having got to the bottom of this, is use MemAvailable
if it is there, and otherwise use half the physical RAM size. Since I will have to read /proc/meminfo
to find out if MemAvailable
is there, there's no point in having Bionic LibC read it again if I call sysconf().
Upvotes: 0
Reputation: 1682
if you want to determine available memory in android , then you can check or go to in perspective - >ddms 2) second thing is you can use memory analyzer tools checked in used and unused memory, you also check availability of memory.
Upvotes: 2
Reputation: 1648
If you use Android NDK:
#include <unistd.h>
size_t getTotalSystemMemory()
{
long pages = sysconf(_SC_PHYS_PAGES);
long page_size = sysconf(_SC_PAGE_SIZE);
return pages * page_size;
}
size_t getFreeSystemMemory()
{
long pages = sysconf(_SC_AVPHYS_PAGES);
long page_size = sysconf(_SC_PAGE_SIZE);
return pages * page_size;
}
Upvotes: 1
Reputation: 86
Would this work?
MemoryInfo mi = new MemoryInfo();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.getMemoryInfo(mi);
long availableMegs = mi.availMem / 1048576L;
Upvotes: 0