• Android 7.1 设置-内存


    平台

         RK3288 + Android 7.1

    概述

    查看系统内存使用情况, 如下图所示:
    在这里插入图片描述

    流程解读

    一些字符显示

    在这里插入图片描述
    2.
    在这里插入图片描述

    packages/apps/Settings/AndroidManifest.xml [入口]

            <activity android:name="Settings$MemorySettingsActivity"
                    android:label="@string/memory_settings_title"
                    android:icon="@drawable/ic_settings_memory"
                    android:taskAffinity="">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="com.android.settings.SHORTCUT" />
                intent-filter>
                <intent-filter android:priority="3">
                    <action android:name="com.android.settings.action.SETTINGS" />
                intent-filter>
                <meta-data android:name="com.android.settings.category"
                    android:value="com.android.settings.category.device" />
                <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                    android:value="com.android.settings.applications.ProcessStatsSummary" />
            activity>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    相关源码

    packages/apps/Settings/src/com/android/settings/applications/ProcessStatsSummary.java
    packages/apps/Settings/src/com/android/settings/applications/ProcessStatsBase.java
    packages/apps/Settings/src/com/android/settings/applications/ProcStatsData.java
    packages/apps/Settings/src/com/android/settings/applications/ProcStatsPackageEntry.java
    packages/apps/Settings/src/com/android/settings/applications/ProcessStatsUi.java
    frameworks/base/services/core/java/com/android/server/am/ProcessStatsService.java
    frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java

    SettingsPreferenceFragment
    ProcessStatsBase
    ProcStatsData mStatsManager
    refreshUi()
    ProcessStatsSummary
    ProcessStatsUi
    ProcStatsData
    ArrayList pkgEntries
    getEntries()
    setDuration(long duration)
    getMemInfo()
    refreshStats()
    ProcStatsEntry
    ProcStatsPackageEntry
    ProcessStatsUi ProcStatsData ProcessStats IProcessStats ProcessStatsService ProcStatsData.MemInfo ActivityManager onResume() refreshStats() load() getStatsOverTime() getStatsOverTime() read() computeTotalMemoryUse() new MemInfo() getMemoryInfo() createPkgMap() createOsEntry() refreshUi() getMemInfo() ProcessStatsUi ProcStatsData ProcessStats IProcessStats ProcessStatsService ProcStatsData.MemInfo ActivityManager

    frameworks/base/services/core/java/com/android/server/am/ProcessStatsService.java

        public ParcelFileDescriptor getStatsOverTime(long minTime) {
            mAm.mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.PACKAGE_USAGE_STATS, null);
            Parcel current = Parcel.obtain();
            long curTime;
            synchronized (mAm) {
                long now = SystemClock.uptimeMillis();
                mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
                mProcessStats.mTimePeriodEndUptime = now;
                mProcessStats.writeToParcel(current, now, 0);
                curTime = mProcessStats.mTimePeriodEndRealtime
                        - mProcessStats.mTimePeriodStartRealtime;
            }
            mWriteLock.lock();
            try {
                if (curTime < minTime) {
                    // Need to add in older stats to reach desired time.
                    ArrayList<String> files = getCommittedFiles(0, false, true);
                    if (files != null && files.size() > 0) {
                        current.setDataPosition(0);
                        ProcessStats stats = ProcessStats.CREATOR.createFromParcel(current);
                        current.recycle();
                        int i = files.size()-1;
                        while (i >= 0 && (stats.mTimePeriodEndRealtime
                                - stats.mTimePeriodStartRealtime) < minTime) {
                            AtomicFile file = new AtomicFile(new File(files.get(i)));
                            i--;
                            ProcessStats moreStats = new ProcessStats(false);
                            readLocked(moreStats, file);
                            if (moreStats.mReadError == null) {
                                stats.add(moreStats);
                                StringBuilder sb = new StringBuilder();
                                sb.append("Added stats: ");
                                sb.append(moreStats.mTimePeriodStartClockStr);
                                sb.append(", over ");
                                TimeUtils.formatDuration(moreStats.mTimePeriodEndRealtime
                                        - moreStats.mTimePeriodStartRealtime, sb);
                                Slog.i(TAG, sb.toString());
                            } else {
                                Slog.w(TAG, "Failure reading " + files.get(i+1) + "; "
                                        + moreStats.mReadError);
                                continue;
                            }
                        }
                        current = Parcel.obtain();
                        stats.writeToParcel(current, 0);
                    }
                }
                final byte[] outData = current.marshall();
                current.recycle();
                final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
                Thread thr = new Thread("ProcessStats pipe output") {
                    public void run() {
                        FileOutputStream fout = new ParcelFileDescriptor.AutoCloseOutputStream(fds[1]);
                        try {
                            fout.write(outData);
                            fout.close();
                        } catch (IOException e) {
                            Slog.w(TAG, "Failure writing pipe", e);
                        }
                    }
                };
                thr.start();
                return fds[0];
            } catch (IOException e) {
                Slog.w(TAG, "Failed building output pipe", e);
            } finally {
                mWriteLock.unlock();
            }
            return null;
        }
        
        private ArrayList<String> getCommittedFiles(int minNum, boolean inclCurrent,
                boolean inclCheckedIn) {
            File[] files = mBaseDir.listFiles();
            if (files == null || files.length <= minNum) {
                return null;
            }
            ArrayList<String> filesArray = new ArrayList<String>(files.length);
            String currentFile = mFile.getBaseFile().getPath();
            if (DEBUG) Slog.d(TAG, "Collecting " + files.length + " files except: " + currentFile);
            for (int i=0; i<files.length; i++) {
                File file = files[i];
                String fileStr = file.getPath();
                if (DEBUG) Slog.d(TAG, "Collecting: " + fileStr);
                if (!inclCheckedIn && fileStr.endsWith(STATE_FILE_CHECKIN_SUFFIX)) {
                    if (DEBUG) Slog.d(TAG, "Skipping: already checked in");
                    continue;
                }
                if (!inclCurrent && fileStr.equals(currentFile)) {
                    if (DEBUG) Slog.d(TAG, "Skipping: current stats");
                    continue;
                }
                filesArray.add(fileStr);
            }
            Collections.sort(filesArray);
            return filesArray;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98

    mBaseDir 是由ActivityManagerService 创建ProcessStatsService时传进来的:

    frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

        // Note: This method is invoked on the main thread but may need to attach various
        // handlers to other threads.  So take care to be explicit about the looper.
        public ActivityManagerService(Context systemContext) {
            //.......
            // TODO: Move creation of battery stats service outside of activity manager service.
            File dataDir = Environment.getDataDirectory();
            File systemDir = new File(dataDir, "system");
            mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    最终可以看到, ProcessStatsService会去读取data/system/procstats目录下的文件, 并解析传递数据

    rk3288:/data/system/procstats # ll
    total 160
    -rw------- 1 system system 11276 2013-01-19 13:45 state-2013-01-19-10-44-19.bin
    -rw------- 1 system system  7684 2013-01-19 16:47 state-2013-01-19-13-45-00.bin
    -rw------- 1 system system  7508 2013-01-19 19:49 state-2013-01-19-16-47-00.bin
    -rw------- 1 system system  7508 2013-01-19 22:50 state-2013-01-19-19-49-00.bin
    -rw------- 1 system system  7912 2013-01-20 01:52 state-2013-01-19-22-50-00.bin
    -rw------- 1 system system  7896 2013-01-20 04:54 state-2013-01-20-01-52-00.bin
    -rw------- 1 system system  8280 2013-01-20 07:56 state-2013-01-20-04-54-00.bin
    -rw------- 1 system system  7672 2013-01-20 10:58 state-2013-01-20-07-56-00.bin
    -rw------- 1 system system  7656 2013-01-20 11:58 state-2013-01-20-10-58-00.bin
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    procstats文件的读取:

        static byte[] readFully(InputStream stream, int[] outLen) throws IOException {
            int pos = 0;
            final int initialAvail = stream.available();
            byte[] data = new byte[initialAvail > 0 ? (initialAvail+1) : 16384];
            while (true) {
                int amt = stream.read(data, pos, data.length-pos);
                if (DEBUG_PARCEL) Slog.i("foo", "Read " + amt + " bytes at " + pos
                        + " of avail " + data.length);
                if (amt < 0) {
                    if (DEBUG_PARCEL) Slog.i("foo", "**** FINISHED READING: pos=" + pos
                            + " len=" + data.length);
                    outLen[0] = pos;
                    return data;
                }
                pos += amt;
                if (pos >= data.length) {
                    byte[] newData = new byte[pos+16384];
                    if (DEBUG_PARCEL) Slog.i(TAG, "Copying " + pos + " bytes to new array len "
                            + newData.length);
                    System.arraycopy(data, 0, newData, 0, pos);
                    data = newData;
                }
            }
        }
    
        public void read(InputStream stream) {
            try {
                int[] len = new int[1];
                byte[] raw = readFully(stream, len);
                Parcel in = Parcel.obtain();
                in.unmarshall(raw, 0, len[0]);
                in.setDataPosition(0);
                stream.close();
    
                readFromParcel(in);
            } catch (IOException e) {
                mReadError = "caught exception: " + e;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    扩展

    1. dumpsys procstats详解
    2. 查看 RAM 使用情况数据 (procstats)
      在这里插入图片描述
    3. 使用内存性能分析器查看应用的内存使用情况
  • 相关阅读:
    大龄程序员三战考研变身考研战神
    【iOS逆向与安全】DTRpcClient 抓包和代码分析记录
    sed编辑器
    Go语言 Map教程
    Mysql之多表查询下篇
    织梦翻译插件-织梦自动采集翻译插件
    浏览器输入网址后发生了什么?
    校友录系统
    VUE 笔记 生命周期函数
    心法利器[69] | 聊聊数据敏感性
  • 原文地址:https://blog.csdn.net/ansondroider/article/details/125916641