Android 内存参数

372 阅读2分钟

一、内存&空间信息

  • 系统内存情况: 当系统可用内存很小(低于 MemTotal 的 10%)时,OOM、大量 GC、系统频繁自杀拉起等问题都非常容易出现
ActivityManager activityManager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(memoryInfo);
return "当前系统处于低内存状态:" + memoryInfo.lowMemory + " avail Mem:" + getMb(memoryInfo.availMem)
        + " 如果availMem>=" + memoryInfo.threshold + "时触发Low Memory Killer机制";     
  • 应用使用内存:
Runtime runtime = Runtime.getRuntime();
String usedMemorySize = Formatter.formatFileSize(ctx, runtime.totalMemory() - runtime.freeMemory());
String theoryAvailHeapSize = Formatter.formatFileSize(ctx, runtime.maxMemory());
return "当前进程Java虚拟机已用堆内存:" + usedMemorySize + " 理论最大可用内存:" + theoryAvailHeapSize;     
/**
 * @return 系统内部存储可用空间
 */
public static String getAvailableInternalMemorySize(Context ctx) {
    File path = Environment.getDataDirectory();
    StatFs stat = new StatFs(path.getPath());
    long blockSize = stat.getBlockSizeLong();
    long availableBlocks = stat.getAvailableBlocksLong();
    return Formatter.formatFileSize(ctx, availableBlocks * blockSize);
}

/**
 * @return 系统外部存储可用空间
 */
public static String getAvailableExternalMemorySize(Context ctx) {
    if (externalMemoryAvailable()) {
        File path = Environment.getExternalStorageDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize = stat.getBlockSizeLong();
        long availableBlocks = stat.getAvailableBlocksLong();
        return Formatter.formatFileSize(ctx, availableBlocks * blockSize);
    } else {
        return "ERROR";
    }
}
  • 进程整体概况 /proc/pid/status
Name: com.xmamiga.name   // 进程名
State: R (running) 
FDSize: 256         //该字段是表示当前进程分配过的文件描述符的近似的最高值。如果刚开始打开了18个文件,则这里的FDSize等于32,若大于32,则以32为单位递增,例如33则是64;这个32的单位是依赖于系统位数的,如果是32位则是32,若是64位系统则是以64倍增。
VmPeak: 2070428 kB  //虚拟内存峰值
VmSize: 2056588 kB  //已经使用的虚拟内存大小
VmLck: 0 kB         //已经锁住的物理内存的大小(锁住的物理内存不能交换到硬盘)
VmPin: 0 kB 
VmHWM: 205460 kB    //进程所使用的物理内存的峰值
VmRSS: 194716 kB    //进程当前使用的物理内存的大小
VmData: 314280 kB   //进程占用的数据段大小
VmStk: 8196 kB      //进程占用的栈大小
VmExe: 20 kB        //进程占用的代码段大小(不包括库)
VmLib: 188660 kB    //进程所加载的动态库所占用的内存大小(可能与其它进程共享)
VmPTE: 1364 kB      //进程占用的页表大小(交换表项数量)
VmPMD: 16 kB V
mSwap: 5312 kB      //进程所使用的交换区的大小
Threads: 98

二、资源信息

  • 线程数 Thread.activeCount()

    一个线程可能就占 2MB 的虚拟内存,过多的线程会对虚拟内存和文件句柄带来压力。一般如果线程数超过 400 个就比较危险。

    ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
    int count = threadGroup.activeCount();
    Thread[] threads = new Thread[count];
    int enumerateCount = threadGroup.enumerate(threads);
    for (int i = 0; i < enumerateCount; i++) {
        Thread thread = threads[i];
        QLog.d("ThreadInfo: ",thread.getName() + " Priority:" + thread.getPriority() + " State:" +thread.getState());
    } 
    
    
    列举线程所有信息(举例)
    queued-work-looper Priority:5 State:RUNNABLE
    queued-work-looper Priority:5 State:RUNNABLE
    CrAsyncTask #1 Priority:5 State:TIMED_WAITING
    QAV Priority:5 State:RUNNABLE
    QAVStorage Priority:5 State:RUNNABLE
    HomeTask #1 Priority:5 State:WAITING
    
  • 系统最大线程数

    如果超过系统最大线程数,在创建时也会抛出oom cat /proc/sys/kernel/threads-max 权限问题,暂没有获取到 参考资料:mccxj.github.io/blog/201712…

  • 文件句柄 fd

    最大文件句柄数: /proc/pid/limits (内容见下表)

    一般单个进程允许打开的最大文件句柄个数为 1024。但是如果文件句柄超过 800 个就比较危险,需要将所有的 fd 以及对应的文件名输出到日志中,进一步排查是否出现了有文件或者线程的泄露

    Limit                     Soft Limit           Hard Limit           Units     
    Max stack size            8388608              unlimited            bytes     
    Max core file size        0                    unlimited            bytes     
    Max processes             22028                22028                processes 
    Max open files            2048                 4096                 files     // 最大打开文件句柄数
    Max locked memory         65536                65536                bytes     
    Max pending signals       22028                22028                signals   
    Max msgqueue size         819200               819200               bytes     
    Max nice priority         40                   40                   
    Max realtime priority     0                    0                    
    

    获取当前打开文件句柄数: /proc/pid/fd 下文件数量

三、崩溃信息

  • 崩溃所在线程 ——> ACRA中 THREAD_DETAILS的值
  • 崩溃所在Activity ——>