• 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. 使用内存性能分析器查看应用的内存使用情况
  • 相关阅读:
    高清LED显示屏设计制作指南
    Android 插件化
    mysql第十六章 变量,流程控制触发器课后练习
    海思 VI接入视频流程
    基于SSM的概念可视化程序设计学习系统毕业设计源码021009
    XML文件的解析读取(详解)
    算法的复杂度
    【UN-JS-工具类】懒加载的实现 -- 两种方式 --- 一种5行JS实现懒加载
    Linux_应用篇(17) FrameBuffer 应用编程
    基于Android studio实习生招聘系统APP java
  • 原文地址:https://blog.csdn.net/ansondroider/article/details/125916641