栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android 7.1 设置-内存

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android 7.1 设置-内存

平台

     RK3288 + Android 7.1

概述

查看系统内存使用情况, 如下图所示:

流程解读

一些字符显示


2.

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

        
            
                
                
            
            
                
            
            
            
        

相关源码

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

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 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 getCommittedFiles(int minNum, boolean inclCurrent,
            boolean inclCheckedIn) {
        File[] files = mBaseDir.listFiles();
        if (files == null || files.length <= minNum) {
            return null;
        }
        ArrayList filesArray = new ArrayList(files.length);
        String currentFile = mFile.getBaseFile().getPath();
        if (DEBUG) Slog.d(TAG, "Collecting " + files.length + " files except: " + currentFile);
        for (int i=0; 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;
    }

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"));
    }

最终可以看到, 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

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. dumpsys procstats详解
  2. 查看 RAM 使用情况数据 (procstats)
  3. 使用内存性能分析器查看应用的内存使用情况
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1027870.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号