DevSupport

Android获取当前应用的运行内存

2018-11-05  本文已影响0人  Bzaigege

Android获取当前应用的运行内存

题外话,最近在给H5游戏做一个缓存的框架,有个小需求是在WebView界面上显示一个调试框,实时显示缓存信息,包括显示当前的内存大小。本来想网上应该一堆的博客介绍的。心想这样子就美滋滋了,也没多想。但是MMP,一把辛酸泪。

把代码拷贝下来后,发现内存获取显示不对,一直往上飙,100M,200M,300M,400M。但是,Android Profiler 内存分析消耗是不变的,真是日了狗了。没办法找原因啊,网上看了看了一大堆分析的,就想问句,代码有验证过么就发出来?!!!

最后,还得自己解决。分析了下Android Profiler 的内存结构:

image.png

由这几部分组成,然后大家再跟看看系统源码的android.os.Debug.MemoryInfo的这个类,哈哈哈,刚好也有相关的内存结构分类说明:(大家自己翻译理解,我不多说了)

      /**
       * Returns the value of a particular memory statistic or {@code null} if no
       * such memory statistic exists.
       *
       * <p>The following table lists the memory statistics that are supported.
       * Note that memory statistics may be added or removed in a future API level.</p>
       *
       * <table>
       *     <thead>
       *         <tr>
       *             <th>Memory statistic name</th>
       *             <th>Meaning</th>
       *             <th>Example</th>
       *             <th>Supported (API Levels)</th>
       *         </tr>
       *     </thead>
       *     <tbody>
       *         <tr>
       *             <td>summary.java-heap</td>
       *             <td>The private Java Heap usage in kB. This corresponds to the Java Heap field
       *                 in the App Summary section output by dumpsys meminfo.</td>
       *             <td>{@code 1442}</td>
       *             <td>23</td>
       *         </tr>
       *         <tr>
       *             <td>summary.native-heap</td>
       *             <td>The private Native Heap usage in kB. This corresponds to the Native Heap
       *                 field in the App Summary section output by dumpsys meminfo.</td>
       *             <td>{@code 1442}</td>
       *             <td>23</td>
       *         </tr>
       *         <tr>
       *             <td>summary.code</td>
       *             <td>The memory usage for static code and resources in kB. This corresponds to
       *                 the Code field in the App Summary section output by dumpsys meminfo.</td>
       *             <td>{@code 1442}</td>
       *             <td>23</td>
       *         </tr>
       *         <tr>
       *             <td>summary.stack</td>
       *             <td>The stack usage in kB. This corresponds to the Stack field in the
       *                 App Summary section output by dumpsys meminfo.</td>
       *             <td>{@code 1442}</td>
       *             <td>23</td>
       *         </tr>
       *         <tr>
       *             <td>summary.graphics</td>
       *             <td>The graphics usage in kB. This corresponds to the Graphics field in the
       *                 App Summary section output by dumpsys meminfo.</td>
       *             <td>{@code 1442}</td>
       *             <td>23</td>
       *         </tr>
       *         <tr>
       *             <td>summary.private-other</td>
       *             <td>Other private memory usage in kB. This corresponds to the Private Other
       *                 field output in the App Summary section by dumpsys meminfo.</td>
       *             <td>{@code 1442}</td>
       *             <td>23</td>
       *         </tr>
       *         <tr>
       *             <td>summary.system</td>
       *             <td>Shared and system memory usage in kB. This corresponds to the System
       *                 field output in the App Summary section by dumpsys meminfo.</td>
       *             <td>{@code 1442}</td>
       *             <td>23</td>
       *         </tr>
       *         <tr>
       *             <td>summary.total-pss</td>
       *             <td>Total PPS memory usage in kB.</td>
       *             <td>{@code 1442}</td>
       *             <td>23</td>
       *         </tr>
       *         <tr>
       *             <td>summary.total-swap</td>
       *             <td>Total swap usage in kB.</td>
       *             <td>{@code 1442}</td>
       *             <td>23</td>
       *         </tr>
       *     </tbody>
       * </table>
       */
       public String getMemoryStat(String statName) {
            switch(statName) {
                case "summary.java-heap":
                    return Integer.toString(getSummaryJavaHeap());
                case "summary.native-heap":
                    return Integer.toString(getSummaryNativeHeap());
                case "summary.code":
                    return Integer.toString(getSummaryCode());
                case "summary.stack":
                    return Integer.toString(getSummaryStack());
                case "summary.graphics":
                    return Integer.toString(getSummaryGraphics());
                case "summary.private-other":
                    return Integer.toString(getSummaryPrivateOther());
                case "summary.system":
                    return Integer.toString(getSummarySystem());
                case "summary.total-pss":
                    return Integer.toString(getSummaryTotalPss());
                case "summary.total-swap":
                    return Integer.toString(getSummaryTotalSwap());
                default:
                    return null;
            }
        }

        /**
         * Returns a map of the names/values of the memory statistics
         * that {@link #getMemoryStat(String)} supports.
         *
         * @return a map of the names/values of the supported memory statistics.
         */
        public Map<String, String> getMemoryStats() {
            Map<String, String> stats = new HashMap<String, String>();
            stats.put("summary.java-heap", Integer.toString(getSummaryJavaHeap()));
            stats.put("summary.native-heap", Integer.toString(getSummaryNativeHeap()));
            stats.put("summary.code", Integer.toString(getSummaryCode()));
            stats.put("summary.stack", Integer.toString(getSummaryStack()));
            stats.put("summary.graphics", Integer.toString(getSummaryGraphics()));
            stats.put("summary.private-other", Integer.toString(getSummaryPrivateOther()));
            stats.put("summary.system", Integer.toString(getSummarySystem()));
            stats.put("summary.total-pss", Integer.toString(getSummaryTotalPss()));
            stats.put("summary.total-swap", Integer.toString(getSummaryTotalSwap()));
            return stats;
        }

到这里,我们就可以解决问题了,只需要获取到对应的信息就可以了,下面代码供大家参考下。

@TargetApi(Build.VERSION_CODES.M)
    private double getRunningMemory() {
        double mem = 0.0D;
        try {
            // 统计进程的内存信息 totalPss
            final Debug.MemoryInfo[] memInfo = activityManager.getProcessMemoryInfo(new int[]{Process.myPid()});
            if (memInfo.length > 0) {

                /**
                 * 读取内存信息,跟Android Profiler 分析一致
                 */
                String java_mem = memInfo[0].getMemoryStat("summary.java-heap");

                String native_mem = memInfo[0].getMemoryStat("summary.native-heap");

                String graphics_mem = memInfo[0].getMemoryStat("summary.graphics");

                String stack_mem = memInfo[0].getMemoryStat("summary.stack");

                String code_mem = memInfo[0].getMemoryStat("summary.code");

                String others_mem = memInfo[0].getMemoryStat("summary.system");

                final int dalvikPss = ConvertUtils.convertToInt(java_mem,0)
                        + ConvertUtils.convertToInt(native_mem,0)
                        + ConvertUtils.convertToInt(graphics_mem,0)
                        + ConvertUtils.convertToInt(stack_mem,0)
                        + ConvertUtils.convertToInt(code_mem,0)
                        + ConvertUtils.convertToInt(others_mem,0);

                if (dalvikPss >= 0) {
                    // Mem in MB
                    mem = dalvikPss / 1024.0D;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return mem;
    }

    /**
     * 转化为int
     * @param value 传入对象
     * @param defaultValue 发生异常时,返回默认值
     * @return
     */
    public final static int convertToInt(Object value, int defaultValue){

        if (value == null || "".equals(value.toString().trim())){
            return defaultValue;
        }

        try {
            return Integer.valueOf(value.toString());
        }catch (Exception e){

            try {
                return Integer.valueOf(String.valueOf(value));
            }catch (Exception e1) {

                try {
                    return Double.valueOf(value.toString()).intValue();
                }catch (Exception e2){
                    return defaultValue;
                }
            }
        }
    }

实践验证上图:


image.png

结语:

当遇到问题的时候,要多看看源码信息,答案就在其中。

上一篇 下一篇

猜你喜欢

热点阅读