Android内存管理

2,487 阅读2分钟

一、堆与栈

简单而言,栈存放引用、局部变量;堆存放对象实例。

二、进程优先级

Foreground、Visible、Service、Background、Empty

三、ComponentCallback2#onTrimMemory(int level)

四、分配给App的内存大小限制

Item 全称 含义 等价
USS Unique Set Size 物理内存 进程独占的内存
PSS Proportional Set Size 物理内存 PSS= USS+ 按比例包含共享库
RSS Resident Set Size 物理内存 RSS= USS+ 包含共享库
VSS Virtual Set Size 虚拟内存 VSS= RSS+ 未分配实际物理内存
dalvikPrivateDirty(USS) + dalivikSharedDirty == dalvikPSS
nativePrivateDirty + nativePrivateDirty = nativePSS
otherPrivateDirty + otherPrivateDirty = otherPSS

eg : 
"memory_info": { //KB
    "dalvikPrivateDirty": 521816,  
    "dalvikPss": 522449, //510MB
    "dalvikSharedDirty": 1964,
    "nativePrivateDirty": 40468,
    "nativePss": 40984,
    "nativeSharedDirty": 1568,
    "otherPrivateDirty": 281916,
    "otherPss": 323208,
    "otherSharedDirty": 4840,
    "totalPrivateClean": 21768,
    "totalPrivateDirty": 844200,
    "totalPss": 886641,
    "totalSharedClean": 57608,
    "totalSharedDirty": 8372,
    "totalSwappablePss": 21608
  },

系统内存大小获取方式

android.app.ActivityManager.MemoryInfo g_info = new android.app.ActivityManager.MemoryInfo();
android.app.ActivityManager mgr = (android.app.ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
mgr.getMemoryInfo(g_info);
MemoryInfo {
availMem:系统可用内存大小,该值不是绝对的。
totalMem:系统总共内存大小,一般而言是RAM值(偏小)
threshold:系统开始kill后台服务和进程的内存阈值大小
lowMemory:系统处于低内存时该值被置为true
}

eg:
"sys_memory_info": {
    "availMem": 1173463040, //1119MB
    "lowMemory": false, 
    "threshold": 226492416,
    "totalMem": 3905241088
  },

App内存大小获取方式

RunTime rt = Runtime.getRunTime();
Runtime {
    maxMemory:系统可分配给App的最大内存
    freeMemory:App可用内存大小
    total_memory:App当前占用内存
}

系统分配给App的内存限制:
ActivityManager {
    getMemoryClass():系统完美运行时App的最大内存限制, MB
    getLargeMemoryClass():设置为large heap时,系统可分配给App的最大内存 ,MB
}

一般而言:

maxMemory == getMemoryClass()/getLargeMemoryClass()

App Native内存大小

Debug {
    getNativeHeapSize(): native heap大小
    getNativeHeapAllocatedSize() : 获取native已分配的内存大小
    getNativeHeapHeapFreeSize(): 获取native可用内存大小
}

//一般而言:
getNativeHeapSize == getNativeHeapAllocatedSize + getNativeHeapHeapFreeSize


eg:
 "app_memory_info": {
    "native_heap_size": 55574528, // 53MB
    "native_heap_alloc_size": 43496088, //41MB
    "native_heap_free_size": 12078440, //12MB
    "max_memory": 536870912, //512MB
    "free_memory": 2208832, //2M
    "total_memory": 536870912, //512MB
    "memory_class": 384, //384MB
    "large_memory_class": 512 //512MB
  },

五、常用的内存调优分析命令:

  1. dumpsys meminfo
  2. procrank
  3. cat /proc/meminfo
  4. free
  5. showmap
  6. vmstat

六、一些重要的参考知识点

  1. Enum需要的内存通常是static constants的2倍
  2. 每一个class大约占用500bytes,包含匿名类、内部类、局部类、静态类
  3. 每一个object大约占用12~16bytes的RAM
  4. 选择合理的collection