Android 查看进程内存的方式

查看Android系统,单个进程、多个进程内存的使用情况,通常有那些方法:

1,通过Android API函数

使用ActivityManager查看可用内存,具体是其内部类MemoryInfo。

ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();

am.getMemoryInfo(memInfo);

然后通过实例meminfo中的变量读取相关内存信息,如:

public long availMem;

public long totalMem;

public boolean lowMemory; //表示系统是否处于低内存

public long threshold; //表示系统剩余内存低于多少时,认为是低内存。

另外,framework/base/core/java/android/os/Debug.java中,也有一个MemoryInfo内部类,通过它可以查询PSS,VSS,USSS等单个进程使用内存的信息,如:

            int appPID = Process.myPid();            
            int pids[] = new int[1];
            pids[0] = appPID;
            Debug.MemoryInfo[] memoryInfoArray = mActivityManager.getProcessMemoryInfo(pids);
            totalPrivateDirty = memoryInfoArray[0].getTotalPrivateDirty() / BYTES_IN_KILOBYTE;
            totalSharedDirty = memoryInfoArray[0].getTotalSharedDirty() / BYTES_IN_KILOBYTE;
            totalPSS = memoryInfoArray[0].getTotalPss() / BYTES_IN_KILOBYTE;
            nativePSS = memoryInfoArray[0].nativePss / BYTES_IN_KILOBYTE;
            dalvikPSS = memoryInfoArray[0].dalvikPss / BYTES_IN_KILOBYTE;
            otherPSS = memoryInfoArray[0].otherPss / BYTES_IN_KILOBYTE;

这个方式可以得到比较详细的内存使用情况,单位kb,系统中很多内存是进程间共享的,所以某个进程具体使用多少内存是很难精确统计的:

/** The proportional set size for dalvik heap.  (Doesn't include other Dalvik overhead.) */
        public int dalvikPss;
        /** The proportional set size that is swappable for dalvik heap. */
        /** @hide We may want to expose this, eventually. */
        public int dalvikSwappablePss;
        /** The private dirty pages used by dalvik heap. */
        public int dalvikPrivateDirty;
        /** The shared dirty pages used by dalvik heap. */
        public int dalvikSharedDirty;
        /** The private clean pages used by dalvik heap. */
        /** @hide We may want to expose this, eventually. */
        public int dalvikPrivateClean;
        /** The shared clean pages used by dalvik heap. */
        /** @hide We may want to expose this, eventually. */
        public int dalvikSharedClean;
        /** The dirty dalvik pages that have been swapped out. */
        /** @hide We may want to expose this, eventually. */
        public int dalvikSwappedOut;
        /** The dirty dalvik pages that have been swapped out, proportional. */
        /** @hide We may want to expose this, eventually. */
        public int dalvikSwappedOutPss;

        /** The proportional set size for the native heap. */
        public int nativePss;
        /** The proportional set size that is swappable for the native heap. */
        /** @hide We may want to expose this, eventually. */
        public int nativeSwappablePss;
        /** The private dirty pages used by the native heap. */
        public int nativePrivateDirty;
        /** The shared dirty pages used by the native heap. */
        public int nativeSharedDirty;
        /** The private clean pages used by the native heap. */
        /** @hide We may want to expose this, eventually. */
        public int nativePrivateClean;
        /** The shared clean pages used by the native heap. */
        /** @hide We may want to expose this, eventually. */
        public int nativeSharedClean;
        /** The dirty native pages that have been swapped out. */
        /** @hide We may want to expose this, eventually. */
        public int nativeSwappedOut;
        /** The dirty native pages that have been swapped out, proportional. */
        /** @hide We may want to expose this, eventually. */
        public int nativeSwappedOutPss;

        /** The proportional set size for everything else. */
        public int otherPss;
        /** The proportional set size that is swappable for everything else. */
        /** @hide We may want to expose this, eventually. */
        public int otherSwappablePss;
        /** The private dirty pages used by everything else. */
        public int otherPrivateDirty;
        /** The shared dirty pages used by everything else. */
        public int otherSharedDirty;
        /** The private clean pages used by everything else. */
        /** @hide We may want to expose this, eventually. */
        public int otherPrivateClean;
        /** The shared clean pages used by everything else. */
        /** @hide We may want to expose this, eventually. */
        public int otherSharedClean;
        /** The dirty pages used by anyting else that have been swapped out. */
        /** @hide We may want to expose this, eventually. */
        public int otherSwappedOut;
        /** The dirty pages used by anyting else that have been swapped out, proportional. */
        /** @hide We may want to expose this, eventually. */
        public int otherSwappedOutPss;

        /** Whether the kernel reports proportional swap usage */
        /** @hide */
        public boolean hasSwappedOutPss;
其中Dalvik: 是dalvik所使用的内存;

native :是被native堆使用的内存,通常指使用c/c++在堆上分配的内存。

other: 指除去dalvik,native使用的内存,比如分配在栈上的内存。

private: 指私有的,非共享的

share:指共享的内存。

privateDirty: 指非共享的,又不能换页出去的内存大小,如linux为了提高分配内存速度而缓冲的小对象,即使进程结束,该内存也不会释放,只是又重新回到缓冲中。

sharedDirty :指共享的,又不能换页出去的内存大小。

MemoryInfo 描述的内存使用情况可以通过命令adb shell dumpsys meminfo processName/ID得到。

通过public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) @ActivityManager.java可以同时得到多个进程的内存使用情况。

通过public static native void getMemInfo(long[] outSizes)@Debug.java得到单个进程的内存使用情况。

通过public List getRunningAppProcesses() @ActivityManager.java获取当前运行的所有进程的信息,其中RunningAppProcessInfo中有进程名字,进程id。


2,直接对Android文件进行解析

Android严格说只是一个在linux内核上跑的应用程序,所以一般应用程序的内存使用还是采用Linux的传统方法,因此能通过 proc/ 文件系统的meminfo来分析系统的内存使用情况。/proc/cpuinfo中保存了cpu的相关信息,/proc/meminfo/中保存了系统内存的使用信息。比如proc/meminfo中的信息:

MemTotal :  ***kb

MemFree: **kb

Buffers :**kb

Cached :** kb

系统在运行过程中memfree通过很小,以为系统会尽可能地cache和buffer一些数据,提高下次执行的速度,但是实际这些内存也是可以随时被拿来使用的,所以空闲内存通常是free+cached+buffers,也即是total-used。


3,通过Runtime类查看

通过Android系统的Runtime类,然后执行adb 命令(top,procrank,ps等)可以实现查询功能,通过将执行结果进行解析,就扩展了Android的查询功能。如:

    public String captureMediaserverInfo() {
        String cm = "ps mediaserver";
        String memoryUsage = null;

        int ch;
        try {
            Process p = Runtime.getRuntime().exec(cm);
            InputStream in = p.getInputStream();
            StringBuffer sb = new StringBuffer(512);
            while ((ch = in.read()) != -1) {
                sb.append((char) ch);
            }
            memoryUsage = sb.toString();
        } catch (IOException e) {
            Log.v(TAG, e.toString());
        }
        String[] poList = memoryUsage.split("\r|\n|\r\n");
        // A new media.log is enabled with ro.test_harness is set.
        // The output of "ps mediaserver" will include the
        // media.log process in the first line. Update the parsing
        // to only read the thrid line.
        // Smaple ps mediaserver output:
        // USER     PID   PPID  VSIZE  RSS     WCHAN    PC         NAME
        // media     131   1     13676  4796  ffffffff 400b1bd0 S media.log
        // media     219   131   37768  6892  ffffffff 400b236c S /system/bin/mediaserver
        String memusage = poList[poList.length-1].concat("\n");
        return memusage;
    }
类似的命令"system/bin/top -n l","system/bin/procrank",内存消耗的表示:

VSS:virtual set size ,虚拟耗用内存(包含共享库占用的内存)。

RSS: Resident Set Size ,实际使用物理内存(包含共享库占用的内存)。

PSS:Proportional Set Size,实际使用的物理内存(比例分配共享库占用的内存)。

USS:Unique Set Size,进程独自占用的物理内存(不包括共享库占用的内存)。


4,通过DDMS工具(Dalvik debug Monitor Service)

可以查看内存,cpu的使用情况。

选中要检测的进程,单击Update Heap 图标,然后点击Heap试图中的 CauseGC按钮,在Heap试图中可以看到当前选中进程的内存使用情况。


5,使用Debug的方法

public static native long getNativeHeapSize(); //返回当前进程native堆总的内存大小。

public static native long getNativeHeapFreeSize();//返回当前native堆中剩余内存大小。

public static native long getNativeHeapAllocatedSize();//返回当前进程native堆中已使用内存大小。


6,使用 adb shell procrank命令,查看所有进程的内存使用情况。

配合procrank,使用top命令查看某个进程的内存,可以创建一个脚本memRecord.sh,作用是指定程序每隔一秒输出某个进程的内存使用情况:

#! /bin/bash

while true; do

adb shell procrank | grep "com.android.gallery"

sleep 1

done


使用top命令查看内存具体为:

adb shell top -m 10 //查看使用资源最多的10个进程

adb shell top | grep com.android.gallery //查看gallery进程的内存


free 命令,用来显示内存的使用情况,格式:

free [-b -k -m ] [ -o ] [ -s delay] [ -t ] [ -v] 

参数:-b -k -m 表示分别以字节(kb,mb)为单位显示内存使用情况

参数:-s delay ,表示每隔多少秒来显示一次内存使用情况

参数:-t ,显示内存总和列

参数:-o ,不显示缓冲区调节列


你可能感兴趣的:(android开发,Java,&Android虚拟机)