http://jcwlw.blog.163.com/blog/static/36773209201111239364514/
http://blog.youkuaiyun.com/zzp16/article/details/6719809
http://wenku.baidu.com/view/05b2d31d650e52ea551898f0.html
GC_FOR_MALLOC means that the GC was triggered because there wasn't enough memory left on the heap to perform an allocation. Might be triggered when new objects are being created. GC_EXPLICIT means that the garbage collector has been explicitly asked to collect, instead of being triggered by high water marks in the heap. Happens all over the place, but most likely when a thread is being killed or when a binder communication is taken down. There are a few others as well: GC_CONCURRENT Triggered when the heap has reached a certain amount of objects to collect. GC_EXTERNAL_ALLOC means that the the VM is trying to reduce the amount of memory used for collectable objects, to make room for more non-collectable. typedefenum{
|
GC_EXTERNAL_ALLOC freed 297K, 49% free 3411K/6663K, external 24870K/26260K, paused 83ms
这里边的每个数字都是什么意思阿?
free 3411K/6663K和external 24870K/26260K,分别都是表示什么的阿?
释放了297K,现在Free的内存是49%,已用的内存是3411,总得内存是6663
自问自答:
前面Free的内存是VM中java使用的内存,external是指VM中通过JNI中Native的类中的malloc分配出的内存,例如Bitmap和一些Cursor都是这么分配的。
在Davilk中,给一个程序分配的内存根据机型厂商的不同,而不同,现在的大部分的是32M了,而在VM内部会把这些内存分成java使用的内存和 Native使用的内存,它们之间是不能共享的,就是说当你的Native内存用完了,现在Java又有空闲的内存,这时Native会重新像VM申请,而不是直接使用java的。
例如上边的例子
free 3411K/6663K和external 24870K/26260K
如果这时需要创建一个2M的Bitmap,Native现有内存26260-24870=1390K<2048k,因此他就会向Vm申请内存,虽然java空闲的内存是
6663-3411=3252>2048,但这部分内存Native是不能使用。
但是你现在去申请2M的Native内存,VM会告诉你无法分配的,因为现在已使用的内存已经接近峰值了32M(26260+6663=32923 ),所以现在就会成force close 报OOM。
所以现在我们要检查我们的native内存的使用情况来避免OOM。
总结:通过Heap可以查看到Java使用内存情况,但是无法查看JNI使用内存的情况,所以遇到内存溢出时,项目要是调用到动态库的,就留意一下通过JNI申请的内存是否合理释放。
从什么地方可以看出每个应用程序最大的可以用内存是32M
答案:可以使用命令 adb shell dumpsys meminfo com.bb 或者当内存溢出时 Out of memory: Heap Size=8263KB, Allocated=3812KB, Bitmap Size=14235KB,Limit=32768KB
Limit=32768KB便是最大可用内存
但是不同的手机,似乎最大内存限制不一样,下面是我的小手机查出的limit==20480.,不清楚是不是由于系统不完全一样的原因(小手机是2.3.3),还是由手机厂商控制的
native dalvik other total limit bitmap nativeBm
p
size: 7136 6759 N/A 13895 20480 N/A N/A
解释 :Out of memory: Heap Size=19783KB, Allocated=17291KB, Bitmap Size=734KB, Limit=20480KB
Heap Size=19783KB 是堆大小
Bitmap Size=734KB 图片大小
Allocated=17291KB 不知道什么意思
Limit=20480KB 最大上限
当 Heap Size + Bitmap Size > Limit 就会OOM
======================================= 内存分配======================================
Debug.MemoryInfo[] memoryInfo中参数的意思
dalvikPrivateDirty: The private dirty pages used by dalvik。
dalvikPss :The proportional set size for dalvik.
dalvikSharedDirty :The shared dirty pages used by dalvik.
nativePrivateDirty :The private dirty pages used by the native heap.
nativePss :The proportional set size for the native heap.
nativeSharedDirty :The shared dirty pages used by the native heap.
otherPrivateDirty :The private dirty pages used by everything else.
otherPss :The proportional set size for everything else.
otherSharedDirty :The shared dirty pages used by everything else.
Android和Linux一样有大量内存在进程之间进程共享。某个进程准确的使用好多内存实际上是很难统计的。
因为有paging out to disk(换页),所以如果你把所有映射到进程的内存相加,它可能大于你的内存的实际物理大小。
dalvik:是指dalvik所使用的内存。
native:是被native堆使用的内存。应该指使用C\C++在堆上分配的内存。
other:是指除dalvik和native使用的内存。但是具体是指什么呢?至少包括在C\C++分配的非堆内存,比如分配在栈上的内存。puzlle!
private:是指私有的。非共享的。
share:是指共享的内存。
PSS:实际使用的物理内存(比例分配共享库占用的内存)
Pss:它是把共享内存根据一定比例分摊到共享它的各个进程来计算所得到进程使用内存。网上又说是比例分配共享库占用的内存,那么至于这里的共享是否只是库的共享,还是不清楚。
PrivateDirty:它是指非共享的,又不能换页出去(can not be paged to disk )的内存的大小。比如Linux为了提高分配内存速度而缓冲的小对象,即使你的进程结束,该内存也不会释放掉,它只是又重新回到缓冲中而已。
SharedDirty:参照PrivateDirty我认为它应该是指共享的,又不能换页出去(can not be paged to disk )的内存的大小。比如Linux为了提高分配内存速度而缓冲的小对象,即使所有共享它的进程结束,该内存也不会释放掉,它只是又重新回到缓冲中而已
======================== 如何用命令查看内存================
http://blog.youkuaiyun.com/vincew/article/details/6836319
用以下命令可以查看程序的内存使用情况:
|
用android自带的launcher程序为例:
|
|
命令二 "adb shell cat /proc/meminfo 参考http://blog.youkuaiyun.com/kieven2008/article/details/6445421
意思是直接对Android文件进行解析查询,
/proc/cpuinfo系统CPU的类型等多种信息。
/proc/meminfo 系统内存使用信息
如
/proc/meminfo
MemTotal: 16344972 kB
MemFree: 13634064 kB
Buffers: 3656 kB
Cached: 1195708 kB
我们查看机器内存时,会发现MemFree的值很小。这主要是因为,在linux中有这么一种思想,内存不用白不用,因此它尽可能的cache和buffer一些数据,以方便下次使用。但实际上这些内存也是可以立刻拿来使用的。
所以 空闲内存=free+buffers+cached=total-used
通过读取文件/proc/meminfo的信息获取Memory的总量。
ActivityManager. getMemoryInfo(ActivityManager.MemoryInfo)获取当前的可用Memory量。
命令三:adb shell procrank
If you just want to look at memory usage across all processes, you can use the command "adb shell procrank". Output of this on the same system looks like:
PID Vss Rss Pss Uss cmdline 890 84456K 48668K 25850K 21284K system_server 1231 50748K 39088K 17587K 13792K com.android.launcher2 947 34488K 28528K 10834K 9308K com.android.wallpaper 987 26964K 26956K 8751K 7308K com.google.process.gapps 954 24300K 24296K 6249K 4824K com.android.phone 948 23020K 23016K 5864K 4748K com.android.inputmethod.latin 888 25728K 25724K 5774K 3668K zygote 977 24100K 24096K 5667K 4340K android.process.acore ... 59 336K 332K 99K 92K /system/bin/installd 60 396K 392K 93K 84K /system/bin/keystore 51 280K 276K 74K 68K /system/bin/servicemanager 54 256K 252K 69K 64K /system/bin/debuggerd
内存耗用:VSS/RSS/PSS/USS
Terms
• VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
• RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)
• PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
• USS - Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)
一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS
USS is the total private memory for a process, i.e. that memory that is completely unique to that process.USS is an extremely useful number because it indicates the true incremental cost of running a particular process. When a process is killed, the USS is the total memory that is actually returned to the system. USS is the best number to watch when initially suspicious of memory leaks in a process.
============================避免内存溢出的其他事项==============
http://wenku.baidu.com/view/6bca3f6b25c52cc58bd6bebf.html