Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8883ced1 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Implement issue #11050739: Show swapped out RAM

Add "swapped out" field to mem info everywhere.

Change-Id: I89abe8eb0e91fa5c193da93815dc592593c8a3c8
parent 27d3c0fe
Loading
Loading
Loading
Loading
+36 −28
Original line number Original line Diff line number Diff line
@@ -533,8 +533,10 @@ public final class ActivityThread {
    private native void dumpGraphicsInfo(FileDescriptor fd);
    private native void dumpGraphicsInfo(FileDescriptor fd);


    private class ApplicationThread extends ApplicationThreadNative {
    private class ApplicationThread extends ApplicationThreadNative {
        private static final String HEAP_FULL_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s";
        private static final String HEAP_FULL_COLUMN
        private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s";
                = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s";
        private static final String HEAP_COLUMN
                = "%13s %8s %8s %8s %8s %8s %8s %8s";
        private static final String ONE_COUNT_COLUMN = "%21s %8d";
        private static final String ONE_COUNT_COLUMN = "%21s %8d";
        private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
        private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
        private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";
        private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";
@@ -1039,34 +1041,36 @@ public final class ActivityThread {
            // otherwise, show human-readable format
            // otherwise, show human-readable format
            if (dumpFullInfo) {
            if (dumpFullInfo) {
                printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private",
                printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private",
                        "Shared", "Private", "Heap", "Heap", "Heap");
                        "Shared", "Private", "Swapped", "Heap", "Heap", "Heap");
                printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty",
                printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty",
                        "Clean", "Clean", "Size", "Alloc", "Free");
                        "Clean", "Clean", "Dirty", "Size", "Alloc", "Free");
                printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------",
                printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------",
                        "------", "------", "------", "------", "------");
                        "------", "------", "------", "------", "------", "------");
                printRow(pw, HEAP_FULL_COLUMN, "Native Heap", memInfo.nativePss,
                printRow(pw, HEAP_FULL_COLUMN, "Native Heap", memInfo.nativePss,
                        memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
                        memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
                        memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
                        memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
                        memInfo.nativePrivateClean, nativeMax, nativeAllocated, nativeFree);
                        memInfo.nativePrivateClean, memInfo.nativeSwappedOut,
                        nativeMax, nativeAllocated, nativeFree);
                printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
                printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
                        memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
                        memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
                        memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
                        memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
                        memInfo.dalvikPrivateClean, dalvikMax, dalvikAllocated, dalvikFree);
                        memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
                        dalvikMax, dalvikAllocated, dalvikFree);
            } else {
            } else {
                printRow(pw, HEAP_COLUMN, "", "Pss", "Pss", "Private",
                printRow(pw, HEAP_COLUMN, "", "Pss", "Private",
                        "Private", "Heap", "Heap", "Heap");
                        "Private", "Swapped", "Heap", "Heap", "Heap");
                printRow(pw, HEAP_COLUMN, "", "Total", "Clean", "Dirty",
                printRow(pw, HEAP_COLUMN, "", "Total", "Dirty",
                        "Clean", "Size", "Alloc", "Free");
                        "Clean", "Dirty", "Size", "Alloc", "Free");
                printRow(pw, HEAP_COLUMN, "", "------", "------", "------",
                printRow(pw, HEAP_COLUMN, "", "------", "------", "------",
                        "------", "------", "------", "------");
                        "------", "------", "------", "------", "------");
                printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss,
                printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss,
                        memInfo.nativeSwappablePss,
                        memInfo.nativePrivateDirty,
                        memInfo.nativePrivateDirty,
                        memInfo.nativePrivateClean, nativeMax, nativeAllocated, nativeFree);
                        memInfo.nativePrivateClean, memInfo.nativeSwappedOut,
                        nativeMax, nativeAllocated, nativeFree);
                printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
                printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
                        memInfo.dalvikSwappablePss,
                        memInfo.dalvikPrivateDirty,
                        memInfo.dalvikPrivateDirty,
                        memInfo.dalvikPrivateClean, dalvikMax, dalvikAllocated, dalvikFree);
                        memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
                        dalvikMax, dalvikAllocated, dalvikFree);
            }
            }


            int otherPss = memInfo.otherPss;
            int otherPss = memInfo.otherPss;
@@ -1075,6 +1079,7 @@ public final class ActivityThread {
            int otherPrivateDirty = memInfo.otherPrivateDirty;
            int otherPrivateDirty = memInfo.otherPrivateDirty;
            int otherSharedClean = memInfo.otherSharedClean;
            int otherSharedClean = memInfo.otherSharedClean;
            int otherPrivateClean = memInfo.otherPrivateClean;
            int otherPrivateClean = memInfo.otherPrivateClean;
            int otherSwappedOut = memInfo.otherSwappedOut;


            for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
            for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
                final int myPss = memInfo.getOtherPss(i);
                final int myPss = memInfo.getOtherPss(i);
@@ -1083,16 +1088,17 @@ public final class ActivityThread {
                final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
                final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
                final int mySharedClean = memInfo.getOtherSharedClean(i);
                final int mySharedClean = memInfo.getOtherSharedClean(i);
                final int myPrivateClean = memInfo.getOtherPrivateClean(i);
                final int myPrivateClean = memInfo.getOtherPrivateClean(i);
                final int mySwappedOut = memInfo.getOtherSwappedOut(i);
                if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
                if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
                        || mySharedClean != 0 || myPrivateClean != 0) {
                        || mySharedClean != 0 || myPrivateClean != 0 || mySwappedOut != 0) {
                    if (dumpFullInfo) {
                    if (dumpFullInfo) {
                        printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
                        printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
                                myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
                                myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
                                mySharedClean, myPrivateClean, "", "", "");
                                mySharedClean, myPrivateClean, mySwappedOut, "", "", "");
                    } else {
                    } else {
                        printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
                        printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
                                myPss, mySwappablePss, myPrivateDirty,
                                myPss, myPrivateDirty,
                                myPrivateClean, "", "", "");
                                myPrivateClean, mySwappedOut, "", "", "");
                    }
                    }
                    otherPss -= myPss;
                    otherPss -= myPss;
                    otherSwappablePss -= mySwappablePss;
                    otherSwappablePss -= mySwappablePss;
@@ -1100,27 +1106,28 @@ public final class ActivityThread {
                    otherPrivateDirty -= myPrivateDirty;
                    otherPrivateDirty -= myPrivateDirty;
                    otherSharedClean -= mySharedClean;
                    otherSharedClean -= mySharedClean;
                    otherPrivateClean -= myPrivateClean;
                    otherPrivateClean -= myPrivateClean;
                    otherSwappedOut -= mySwappedOut;
                }
                }
            }
            }


            if (dumpFullInfo) {
            if (dumpFullInfo) {
                printRow(pw, HEAP_FULL_COLUMN, "Unknown", otherPss, otherSwappablePss,
                printRow(pw, HEAP_FULL_COLUMN, "Unknown", otherPss, otherSwappablePss,
                        otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean,
                        otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean,
                        "", "", "");
                        otherSwappedOut, "", "", "");
                printRow(pw, HEAP_FULL_COLUMN, "TOTAL", memInfo.getTotalPss(),
                printRow(pw, HEAP_FULL_COLUMN, "TOTAL", memInfo.getTotalPss(),
                        memInfo.getTotalSwappablePss(),
                        memInfo.getTotalSwappablePss(),
                        memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
                        memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
                        memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
                        memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
                        nativeMax+dalvikMax,
                        memInfo.getTotalSwappedOut(), nativeMax+dalvikMax,
                        nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
                        nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
            } else {
            } else {
                printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSwappablePss,
                printRow(pw, HEAP_COLUMN, "Unknown", otherPss,
                        otherPrivateDirty, otherPrivateClean,
                        otherPrivateDirty, otherPrivateClean, otherSwappedOut,
                        "", "", "");
                        "", "", "");
                printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
                printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
                        memInfo.getTotalSwappablePss(),
                        memInfo.getTotalPrivateDirty(),
                        memInfo.getTotalPrivateDirty(),
                        memInfo.getTotalPrivateClean(),
                        memInfo.getTotalPrivateClean(),
                        memInfo.getTotalSwappedOut(),
                        nativeMax+dalvikMax,
                        nativeMax+dalvikMax,
                        nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
                        nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
            }
            }
@@ -1137,16 +1144,17 @@ public final class ActivityThread {
                    final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
                    final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
                    final int mySharedClean = memInfo.getOtherSharedClean(i);
                    final int mySharedClean = memInfo.getOtherSharedClean(i);
                    final int myPrivateClean = memInfo.getOtherPrivateClean(i);
                    final int myPrivateClean = memInfo.getOtherPrivateClean(i);
                    final int mySwappedOut = memInfo.getOtherSwappedOut(i);
                    if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
                    if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
                            || mySharedClean != 0 || myPrivateClean != 0) {
                            || mySharedClean != 0 || myPrivateClean != 0) {
                        if (dumpFullInfo) {
                        if (dumpFullInfo) {
                            printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
                            printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
                                    myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
                                    myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
                                    mySharedClean, myPrivateClean, "", "", "");
                                    mySharedClean, myPrivateClean, mySwappedOut, "", "", "");
                        } else {
                        } else {
                            printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
                            printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
                                    myPss, mySwappablePss, myPrivateDirty,
                                    myPss, myPrivateDirty,
                                    myPrivateClean, "", "", "");
                                    myPrivateClean, mySwappedOut, "", "", "");
                        }
                        }
                    }
                    }
                }
                }
+32 −4
Original line number Original line Diff line number Diff line
@@ -124,6 +124,9 @@ public final class Debug
        /** The shared clean pages used by dalvik heap. */
        /** The shared clean pages used by dalvik heap. */
        /** @hide We may want to expose this, eventually. */
        /** @hide We may want to expose this, eventually. */
        public int dalvikSharedClean;
        public int dalvikSharedClean;
        /** The dirty dalvik pages that have been swapped out. */
        /** @hide We may want to expose this, eventually. */
        public int dalvikSwappedOut;


        /** The proportional set size for the native heap. */
        /** The proportional set size for the native heap. */
        public int nativePss;
        public int nativePss;
@@ -140,6 +143,9 @@ public final class Debug
        /** The shared clean pages used by the native heap. */
        /** The shared clean pages used by the native heap. */
        /** @hide We may want to expose this, eventually. */
        /** @hide We may want to expose this, eventually. */
        public int nativeSharedClean;
        public int nativeSharedClean;
        /** The dirty native pages that have been swapped out. */
        /** @hide We may want to expose this, eventually. */
        public int nativeSwappedOut;


        /** The proportional set size for everything else. */
        /** The proportional set size for everything else. */
        public int otherPss;
        public int otherPss;
@@ -156,6 +162,9 @@ public final class Debug
        /** The shared clean pages used by everything else. */
        /** The shared clean pages used by everything else. */
        /** @hide We may want to expose this, eventually. */
        /** @hide We may want to expose this, eventually. */
        public int otherSharedClean;
        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;


        /** @hide */
        /** @hide */
        public static final int NUM_OTHER_STATS = 16;
        public static final int NUM_OTHER_STATS = 16;
@@ -164,7 +173,7 @@ public final class Debug
        public static final int NUM_DVK_STATS = 5;
        public static final int NUM_DVK_STATS = 5;


        /** @hide */
        /** @hide */
        public static final int NUM_CATEGORIES = 6;
        public static final int NUM_CATEGORIES = 7;


        /** @hide */
        /** @hide */
        public static final int offsetPss = 0;
        public static final int offsetPss = 0;
@@ -178,7 +187,8 @@ public final class Debug
        public static final int offsetPrivateClean = 4;
        public static final int offsetPrivateClean = 4;
        /** @hide */
        /** @hide */
        public static final int offsetSharedClean = 5;
        public static final int offsetSharedClean = 5;

        /** @hide */
        public static final int offsetSwappedOut = 6;


        private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES];
        private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES];


@@ -236,6 +246,14 @@ public final class Debug
            return dalvikSharedClean + nativeSharedClean + otherSharedClean;
            return dalvikSharedClean + nativeSharedClean + otherSharedClean;
        }
        }


        /**
         * Return total swapped out memory in kB.
         * @hide
         */
        public int getTotalSwappedOut() {
            return dalvikSwappedOut + nativeSwappedOut + otherSwappedOut;
        }

        /** @hide */
        /** @hide */
        public int getOtherPss(int which) {
        public int getOtherPss(int which) {
            return otherStats[which*NUM_CATEGORIES + offsetPss];
            return otherStats[which*NUM_CATEGORIES + offsetPss];
@@ -263,12 +281,16 @@ public final class Debug
            return otherStats[which*NUM_CATEGORIES + offsetPrivateClean];
            return otherStats[which*NUM_CATEGORIES + offsetPrivateClean];
        }
        }



        /** @hide */
        /** @hide */
        public int getOtherSharedClean(int which) {
        public int getOtherSharedClean(int which) {
            return otherStats[which*NUM_CATEGORIES + offsetSharedClean];
            return otherStats[which*NUM_CATEGORIES + offsetSharedClean];
        }
        }


        /** @hide */
        public int getOtherSwappedOut(int which) {
            return otherStats[which*NUM_CATEGORIES + offsetSwappedOut];
        }

        /** @hide */
        /** @hide */
        public static String getOtherLabel(int which) {
        public static String getOtherLabel(int which) {
            switch (which) {
            switch (which) {
@@ -287,7 +309,7 @@ public final class Debug
                case 12: return "Other mmap";
                case 12: return "Other mmap";
                case 13: return "Graphics";
                case 13: return "Graphics";
                case 14: return "GL";
                case 14: return "GL";
                case 15: return "Other memtrack";
                case 15: return "Memtrack";
                case 16: return ".Heap";
                case 16: return ".Heap";
                case 17: return ".LOS";
                case 17: return ".LOS";
                case 18: return ".LinearAlloc";
                case 18: return ".LinearAlloc";
@@ -308,18 +330,21 @@ public final class Debug
            dest.writeInt(dalvikSharedDirty);
            dest.writeInt(dalvikSharedDirty);
            dest.writeInt(dalvikPrivateClean);
            dest.writeInt(dalvikPrivateClean);
            dest.writeInt(dalvikSharedClean);
            dest.writeInt(dalvikSharedClean);
            dest.writeInt(dalvikSwappedOut);
            dest.writeInt(nativePss);
            dest.writeInt(nativePss);
            dest.writeInt(nativeSwappablePss);
            dest.writeInt(nativeSwappablePss);
            dest.writeInt(nativePrivateDirty);
            dest.writeInt(nativePrivateDirty);
            dest.writeInt(nativeSharedDirty);
            dest.writeInt(nativeSharedDirty);
            dest.writeInt(nativePrivateClean);
            dest.writeInt(nativePrivateClean);
            dest.writeInt(nativeSharedClean);
            dest.writeInt(nativeSharedClean);
            dest.writeInt(nativeSwappedOut);
            dest.writeInt(otherPss);
            dest.writeInt(otherPss);
            dest.writeInt(otherSwappablePss);
            dest.writeInt(otherSwappablePss);
            dest.writeInt(otherPrivateDirty);
            dest.writeInt(otherPrivateDirty);
            dest.writeInt(otherSharedDirty);
            dest.writeInt(otherSharedDirty);
            dest.writeInt(otherPrivateClean);
            dest.writeInt(otherPrivateClean);
            dest.writeInt(otherSharedClean);
            dest.writeInt(otherSharedClean);
            dest.writeInt(otherSwappedOut);
            dest.writeIntArray(otherStats);
            dest.writeIntArray(otherStats);
        }
        }


@@ -330,18 +355,21 @@ public final class Debug
            dalvikSharedDirty = source.readInt();
            dalvikSharedDirty = source.readInt();
            dalvikPrivateClean = source.readInt();
            dalvikPrivateClean = source.readInt();
            dalvikSharedClean = source.readInt();
            dalvikSharedClean = source.readInt();
            dalvikSwappedOut = source.readInt();
            nativePss = source.readInt();
            nativePss = source.readInt();
            nativeSwappablePss = source.readInt();
            nativeSwappablePss = source.readInt();
            nativePrivateDirty = source.readInt();
            nativePrivateDirty = source.readInt();
            nativeSharedDirty = source.readInt();
            nativeSharedDirty = source.readInt();
            nativePrivateClean = source.readInt();
            nativePrivateClean = source.readInt();
            nativeSharedClean = source.readInt();
            nativeSharedClean = source.readInt();
            nativeSwappedOut = source.readInt();
            otherPss = source.readInt();
            otherPss = source.readInt();
            otherSwappablePss = source.readInt();
            otherSwappablePss = source.readInt();
            otherPrivateDirty = source.readInt();
            otherPrivateDirty = source.readInt();
            otherSharedDirty = source.readInt();
            otherSharedDirty = source.readInt();
            otherPrivateClean = source.readInt();
            otherPrivateClean = source.readInt();
            otherSharedClean = source.readInt();
            otherSharedClean = source.readInt();
            otherSwappedOut = source.readInt();
            otherStats = source.createIntArray();
            otherStats = source.createIntArray();
        }
        }


+35 −12
Original line number Original line Diff line number Diff line
@@ -80,6 +80,7 @@ struct stat_fields {
    jfieldID sharedDirty_field;
    jfieldID sharedDirty_field;
    jfieldID privateClean_field;
    jfieldID privateClean_field;
    jfieldID sharedClean_field;
    jfieldID sharedClean_field;
    jfieldID swappedOut_field;
};
};


struct stat_field_names {
struct stat_field_names {
@@ -89,14 +90,18 @@ struct stat_field_names {
    const char* sharedDirty_name;
    const char* sharedDirty_name;
    const char* privateClean_name;
    const char* privateClean_name;
    const char* sharedClean_name;
    const char* sharedClean_name;
    const char* swappedOut_name;
};
};


static stat_fields stat_fields[_NUM_CORE_HEAP];
static stat_fields stat_fields[_NUM_CORE_HEAP];


static stat_field_names stat_field_names[_NUM_CORE_HEAP] = {
static stat_field_names stat_field_names[_NUM_CORE_HEAP] = {
    { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty", "otherPrivateClean", "otherSharedClean" },
    { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty",
    { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty", "dalvikPrivateClean", "dalvikSharedClean" },
        "otherPrivateClean", "otherSharedClean", "otherSwappedOut" },
    { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty", "nativePrivateClean", "nativeSharedClean" }
    { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty",
        "dalvikPrivateClean", "dalvikSharedClean", "dalvikSwappedOut" },
    { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty",
        "nativePrivateClean", "nativeSharedClean", "nativeSwappedOut" }
};
};


jfieldID otherStats_field;
jfieldID otherStats_field;
@@ -110,6 +115,7 @@ struct stats_t {
    int sharedDirty;
    int sharedDirty;
    int privateClean;
    int privateClean;
    int sharedClean;
    int sharedClean;
    int swappedOut;
};
};


#define BINDER_STATS "/proc/binder/stats"
#define BINDER_STATS "/proc/binder/stats"
@@ -219,6 +225,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats)
    float sharing_proportion = 0.0;
    float sharing_proportion = 0.0;
    unsigned shared_clean = 0, shared_dirty = 0;
    unsigned shared_clean = 0, shared_dirty = 0;
    unsigned private_clean = 0, private_dirty = 0;
    unsigned private_clean = 0, private_dirty = 0;
    unsigned swapped_out = 0;
    bool is_swappable = false;
    bool is_swappable = false;
    unsigned referenced = 0;
    unsigned referenced = 0;
    unsigned temp;
    unsigned temp;
@@ -333,28 +340,36 @@ static void read_mapinfo(FILE *fp, stats_t* stats)
        //ALOGI("native=%d dalvik=%d sqlite=%d: %s\n", isNativeHeap, isDalvikHeap,
        //ALOGI("native=%d dalvik=%d sqlite=%d: %s\n", isNativeHeap, isDalvikHeap,
        //    isSqliteHeap, line);
        //    isSqliteHeap, line);


        shared_clean = 0;
        shared_dirty = 0;
        private_clean = 0;
        private_dirty = 0;
        swapped_out = 0;

        while (true) {
        while (true) {
            if (fgets(line, 1024, fp) == 0) {
            if (fgets(line, 1024, fp) == 0) {
                done = true;
                done = true;
                break;
                break;
            }
            }


            if (sscanf(line, "Size: %d kB", &temp) == 1) {
            if (line[0] == 'S' && sscanf(line, "Size: %d kB", &temp) == 1) {
                size = temp;
                size = temp;
            } else if (sscanf(line, "Rss: %d kB", &temp) == 1) {
            } else if (line[0] == 'R' && sscanf(line, "Rss: %d kB", &temp) == 1) {
                resident = temp;
                resident = temp;
            } else if (sscanf(line, "Pss: %d kB", &temp) == 1) {
            } else if (line[0] == 'P' && sscanf(line, "Pss: %d kB", &temp) == 1) {
                pss = temp;
                pss = temp;
            } else if (sscanf(line, "Shared_Clean: %d kB", &temp) == 1) {
            } else if (line[0] == 'S' && sscanf(line, "Shared_Clean: %d kB", &temp) == 1) {
                shared_clean = temp;
                shared_clean = temp;
            } else if (sscanf(line, "Shared_Dirty: %d kB", &temp) == 1) {
            } else if (line[0] == 'S' && sscanf(line, "Shared_Dirty: %d kB", &temp) == 1) {
                shared_dirty = temp;
                shared_dirty = temp;
            } else if (sscanf(line, "Private_Clean: %d kB", &temp) == 1) {
            } else if (line[0] == 'P' && sscanf(line, "Private_Clean: %d kB", &temp) == 1) {
                private_clean = temp;
                private_clean = temp;
            } else if (sscanf(line, "Private_Dirty: %d kB", &temp) == 1) {
            } else if (line[0] == 'P' && sscanf(line, "Private_Dirty: %d kB", &temp) == 1) {
                private_dirty = temp;
                private_dirty = temp;
            } else if (sscanf(line, "Referenced: %d kB", &temp) == 1) {
            } else if (line[0] == 'R' && sscanf(line, "Referenced: %d kB", &temp) == 1) {
                referenced = temp;
                referenced = temp;
            } else if (line[0] == 'S' && sscanf(line, "Swap: %d kB", &temp) == 1) {
                swapped_out = temp;
            } else if (strlen(line) > 30 && line[8] == '-' && line[17] == ' ') {
            } else if (strlen(line) > 30 && line[8] == '-' && line[17] == ' ') {
                // looks like a new mapping
                // looks like a new mapping
                // example: "10000000-10001000 ---p 10000000 00:00 0"
                // example: "10000000-10001000 ---p 10000000 00:00 0"
@@ -366,7 +381,8 @@ static void read_mapinfo(FILE *fp, stats_t* stats)
            if (is_swappable && (pss > 0)) {
            if (is_swappable && (pss > 0)) {
                sharing_proportion = 0.0;
                sharing_proportion = 0.0;
                if ((shared_clean > 0) || (shared_dirty > 0)) {
                if ((shared_clean > 0) || (shared_dirty > 0)) {
                    sharing_proportion = (pss - private_clean - private_dirty)/(shared_clean+shared_dirty);
                    sharing_proportion = (pss - private_clean
                            - private_dirty)/(shared_clean+shared_dirty);
                }
                }
                swappable_pss = (sharing_proportion*shared_clean) + private_clean;
                swappable_pss = (sharing_proportion*shared_clean) + private_clean;
            } else
            } else
@@ -378,6 +394,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats)
            stats[whichHeap].sharedDirty += shared_dirty;
            stats[whichHeap].sharedDirty += shared_dirty;
            stats[whichHeap].privateClean += private_clean;
            stats[whichHeap].privateClean += private_clean;
            stats[whichHeap].sharedClean += shared_clean;
            stats[whichHeap].sharedClean += shared_clean;
            stats[whichHeap].swappedOut += swapped_out;
            if (whichHeap == HEAP_DALVIK || whichHeap == HEAP_DALVIK_OTHER) {
            if (whichHeap == HEAP_DALVIK || whichHeap == HEAP_DALVIK_OTHER) {
                stats[subHeap].pss += pss;
                stats[subHeap].pss += pss;
                stats[subHeap].swappablePss += swappable_pss;
                stats[subHeap].swappablePss += swappable_pss;
@@ -385,6 +402,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats)
                stats[subHeap].sharedDirty += shared_dirty;
                stats[subHeap].sharedDirty += shared_dirty;
                stats[subHeap].privateClean += private_clean;
                stats[subHeap].privateClean += private_clean;
                stats[subHeap].sharedClean += shared_clean;
                stats[subHeap].sharedClean += shared_clean;
                stats[subHeap].swappedOut += swapped_out;
            }
            }
        }
        }
    }
    }
@@ -428,6 +446,7 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz,
        stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty;
        stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty;
        stats[HEAP_UNKNOWN].privateClean += stats[i].privateClean;
        stats[HEAP_UNKNOWN].privateClean += stats[i].privateClean;
        stats[HEAP_UNKNOWN].sharedClean += stats[i].sharedClean;
        stats[HEAP_UNKNOWN].sharedClean += stats[i].sharedClean;
        stats[HEAP_UNKNOWN].swappedOut += stats[i].swappedOut;
    }
    }


    for (int i=0; i<_NUM_CORE_HEAP; i++) {
    for (int i=0; i<_NUM_CORE_HEAP; i++) {
@@ -437,6 +456,7 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz,
        env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty);
        env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty);
        env->SetIntField(object, stat_fields[i].privateClean_field, stats[i].privateClean);
        env->SetIntField(object, stat_fields[i].privateClean_field, stats[i].privateClean);
        env->SetIntField(object, stat_fields[i].sharedClean_field, stats[i].sharedClean);
        env->SetIntField(object, stat_fields[i].sharedClean_field, stats[i].sharedClean);
        env->SetIntField(object, stat_fields[i].swappedOut_field, stats[i].swappedOut);
    }
    }




@@ -455,6 +475,7 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz,
        otherArray[j++] = stats[i].sharedDirty;
        otherArray[j++] = stats[i].sharedDirty;
        otherArray[j++] = stats[i].privateClean;
        otherArray[j++] = stats[i].privateClean;
        otherArray[j++] = stats[i].sharedClean;
        otherArray[j++] = stats[i].sharedClean;
        otherArray[j++] = stats[i].swappedOut;
    }
    }


    env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0);
    env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0);
@@ -971,6 +992,8 @@ int register_android_os_Debug(JNIEnv *env)
                env->GetFieldID(clazz, stat_field_names[i].privateClean_name, "I");
                env->GetFieldID(clazz, stat_field_names[i].privateClean_name, "I");
        stat_fields[i].sharedClean_field =
        stat_fields[i].sharedClean_field =
                env->GetFieldID(clazz, stat_field_names[i].sharedClean_name, "I");
                env->GetFieldID(clazz, stat_field_names[i].sharedClean_name, "I");
        stat_fields[i].swappedOut_field =
                env->GetFieldID(clazz, stat_field_names[i].swappedOut_name, "I");
    }
    }


    return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods));
    return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods));