最近在开发flutter app,发现flutter app的内存使用和之前android java app 有很大区别,flutter app 运行时Native heap占大头,android java app运行时, dalvik heep 占大头。
于是重新学习了一遍android内存知识,大致总结如下
1,进程的地址空间分为stack和heap,
stack是栈,由操作系统控制, 函数地址、参数,内部变量都在栈上,栈不大,一般几MB
heap是堆,由程序员控制,所以malloc, new, free 这些操作符来申请、释放堆内存,所以容易出现申请了但不释放等内存泄漏情况
2,native进程,是由c/c++分配的,/system/bin下面的所有程序运行在native进程中
dalvik进程,是由java程序的dalvik虚拟机分配的,dalvik虚拟机的宿主进程是由fork()系统创建的,所以每个java进程都是运行在一个native进程中
android系统的应用程序基本都是java程序
3,OOM
程序运行时经常会出现OOM现象,这个oom并不是没有ram可以用了,而是因为Dalvik heap的使用超过了系统允许的上限,即vm heap 的最大值
Android google之所以这样设计是为了让更多app常驻内存,不用每次启动都要加载资源浪费时间。
4,Ram真的不足
OOM并不是表示Ram不足,但是一旦ram真的不足,即多个app在后台运行时, 系统将会首先杀死优先级不高的app来释放内存
5,如何查看ram使用信息
adb shell cat /proc/meminfo
D:\>adb shell cat /proc/meminfo
MemTotal: 807776 kB
MemFree: 62648 kB
MemAvailable: 186472 kB
Buffers: 2552 kB
Cached: 121752 kB
SwapCached: 140 kB
Active: 211812 kB
Inactive: 270664 kB
Active(anon): 166164 kB
Inactive(anon): 202052 kB
Active(file): 45648 kB
Inactive(file): 68612 kB
Unevictable: 9180 kB
Mlocked: 0 kB
SwapTotal: 511996 kB
SwapFree: 499492 kB
Dirty: 36 kB
Writeback: 0 kB
AnonPages: 367276 kB
Mapped: 50232 kB
Shmem: 864 kB
Slab: 51064 kB
SReclaimable: 23028 kB
SUnreclaim: 28036 kB
KernelStack: 14368 kB
PageTables: 9464 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 915884 kB
Committed_AS: 20248668 kB
VmallocTotal: 1048576 kB
VmallocUsed: 94208 kB
VmallocChunk: 852292 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
6,查看单个进程的内存使用情况
D:\>adb shell dumpsys meminfo com.wocheng.wcy
Applications Memory Usage (kB):
Uptime: 1270811 Realtime: 1270811
** MEMINFO in pid 6768 [com.wocheng.wcy] **
Pss Private Private Swapped Heap Heap Heap
Total Dirty Clean Dirty Size Alloc Free
------ ------ ------ ------ ------ ------ ------
Native Heap 43062 43060 0 20 55264 40004 3403
Dalvik Heap 4258 4252 0 4 4508 4297 211
Dalvik Other 4153 4132 0 76
Stack 296 296 0 0
Other dev 5 0 4 0
.so mmap 7930 464 7092 608
.jar mmap 28 0 28 0
.apk mmap 16 0 4 0
.ttf mmap 734 0 328 0
.dex mmap 4755 400 4088 0
Other mmap 8 4 4 0
GL 46452 46452 0 0
Unknown 12224 12224 0 4
TOTAL 123921 111284 11548 712 59772 44301 3614
7,bitmap为什么容易导致OOM
Bitmap的申请是在dalvik heap上,,所以过多的bitmap会造成oom
8,内存错误过程
Dalvik heap增加到vm heap 最大值,出现OOM
当ram增加到最大值,而且无其他app内存释放使用时,会唤醒memory killer
9, flutter 的内存使用主要在native heap 和GL上, 不太容易OOM,但是使用过多的话容易造成memory killer 引起的闪退