How to get current memory usage in android?
I have used /proc/meminfo and parsed command response.however it result shows that :
MemTotal: 94348 kB MemFree: 5784 kB
means. it shows there is only 5MB free memory. Is it possible with android mobile? There is only 5-6 application installed on my mobile and no other task is running. but still this command shows there is very little free memory.
Can somebody clarify this? or is there any other way of getting memory usage in android?
Solution 1:
CAUTION: This answer measures memory usage/available of the DEVICE. This is NOT what is available to your app. To measure what your APP is doing, and is PERMITTED to do, Use android developer's answer.
Android docs - ActivityManager.MemoryInfo
parse /proc/meminfo command. You can find reference code here: Get Memory Usage in Android
-
use below code and get current RAM:
MemoryInfo mi = new MemoryInfo(); ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); activityManager.getMemoryInfo(mi); double availableMegs = mi.availMem / 0x100000L; //Percentage can be calculated for API 16+ double percentAvail = mi.availMem / (double)mi.totalMem * 100.0;
Explanation of the number 0x100000L
1024 bytes == 1 Kibibyte
1024 Kibibyte == 1 Mebibyte
1024 * 1024 == 1048576
1048576 == 0x100000
It's quite obvious that the number is used to convert from bytes to mebibyte
P.S: we need to calculate total memory only once. so call point 1 only once in your code and then after, you can call code of point 2 repetitively.
Solution 2:
It depends on your definition of what memory query you wish to get.
Usually, you'd like to know the status of the heap memory, since if it uses too much memory, you get OOM and crash the app.
For this, you can check the next values:
final Runtime runtime = Runtime.getRuntime();
final long usedMemInMB=(runtime.totalMemory() - runtime.freeMemory()) / 1048576L;
final long maxHeapSizeInMB=runtime.maxMemory() / 1048576L;
final long availHeapSizeInMB = maxHeapSizeInMB - usedMemInMB;
The more the "usedMemInMB" variable gets close to "maxHeapSizeInMB", the closer availHeapSizeInMB
gets to zero, the closer you get OOM. (Due to memory fragmentation, you may get OOM BEFORE this reaches zero.)
That's also what the DDMS tool of memory usage shows.
Alternatively, there is the real RAM usage, which is how much the entire system uses - see accepted answer to calculate that.
Update: since Android O makes your app also use the native RAM (at least for Bitmaps storage, which is usually the main reason for huge memory usage), and not just the heap, things have changed, and you get less OOM (because the heap doesn't contain bitmaps anymore,check here), but you should still keep an eye on memory use if you suspect you have memory leaks. On Android O, if you have memory leaks that should have caused OOM on older versions, it seems it will just crash without you being able to catch it. Here's how to check for memory usage:
val nativeHeapSize = Debug.getNativeHeapSize()
val nativeHeapFreeSize = Debug.getNativeHeapFreeSize()
val usedMemInBytes = nativeHeapSize - nativeHeapFreeSize
val usedMemInPercentage = usedMemInBytes * 100 / nativeHeapSize
But I believe it might be best to use the profiler of the IDE, which shows the data in real time, using a graph.
So the good news on Android O is that it's much harder to get crashes due to OOM of storing too many large bitmaps, but the bad news is that I don't think it's possible to catch such a case during runtime.
EDIT: seems Debug.getNativeHeapSize()
changes over time, as it shows you the total max memory for your app. So those functions are used only for the profiler, to show how much your app is using.
If you want to get the real total and available native RAM , use this:
val memoryInfo = ActivityManager.MemoryInfo()
(getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager).getMemoryInfo(memoryInfo)
val nativeHeapSize = memoryInfo.totalMem
val nativeHeapFreeSize = memoryInfo.availMem
val usedMemInBytes = nativeHeapSize - nativeHeapFreeSize
val usedMemInPercentage = usedMemInBytes * 100 / nativeHeapSize
Log.d("AppLog", "total:${Formatter.formatFileSize(this, nativeHeapSize)} " +
"free:${Formatter.formatFileSize(this, nativeHeapFreeSize)} " +
"used:${Formatter.formatFileSize(this, usedMemInBytes)} ($usedMemInPercentage%)")
Solution 3:
Here is a way to calculate memory usage of currently running application:
public static long getUsedMemorySize() {
long freeSize = 0L;
long totalSize = 0L;
long usedSize = -1L;
try {
Runtime info = Runtime.getRuntime();
freeSize = info.freeMemory();
totalSize = info.totalMemory();
usedSize = totalSize - freeSize;
} catch (Exception e) {
e.printStackTrace();
}
return usedSize;
}
Solution 4:
Another way (currently showing 25MB free on my G1):
MemoryInfo mi = new MemoryInfo();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.getMemoryInfo(mi);
long availableMegs = mi.availMem / 1048576L;