android性能优化 GPU shader level

82 篇文章 1 订阅

GPU shader level

GPU shader level 是指图形处理单元(GPU)支持的着色器功能级别。着色器是在GPU上运行的小型程序,用于处理图形渲染中的光照、纹理、阴影等效果。

不同的GPU支持不同的着色器功能级别,通常用数字表示。较低的着色器级别支持较少的功能,而较高的级别支持更多的功能。较高的着色器级别通常意味着更高质量的图形渲染效果。

以下是一些常见的 GPU shader level 级别:

Shader Model 2.0:这是较旧的级别,支持基本的顶点和像素着色器功能。它适用于一些较旧的GPU。
Shader Model 3.0:这个级别支持更高级的顶点和像素着色器功能,包括几何着色器和纹理数组等功能。
Shader Model 4.0:这个级别引入了计算着色器,支持更高级的图形计算功能。
Shader Model 5.0:这个级别支持更高级的计算着色器和几何着色器功能,以及更多的纹理采样器。

内存概念

常驻内存缓冲区

常驻内存缓存区是指在应用程序运行过程中一直存在于内存中的一块内存区域,用于临时存储经常被访问或需要频繁读写的数据,以提高数据的访问速度和响应性能。
常驻内存缓存区通常用于存储应用程序所需的数据,如图片、网络请求的结果、数据库查询结果等。这些数据被缓存在内存中,以避免频繁的磁盘读写操作,从而提高数据的读取和写入速度。
常驻内存缓存区由应用程序自己管理,可以使用各种数据结构来实现,如哈希表、链表、LRU(最近最少使用)等。开发人员可以根据应用程序的需求和性能要求,选择合适的数据结构和算法来管理常驻内存缓存区。
需要注意的是,常驻内存缓存区的大小是有限的,因为内存资源是有限的。开发人员需要根据应用程序的需求和设备的内存限制,合理设置常驻内存缓存区的大小,以避免内存溢出或过度占用内存的问题。

PSS

Debug.MemoryInfo()获取PSS更加敏感。
activityManager.getProcessMemoryInfo(pids)获取的PSS都没有变化

public class UtilTest {
    private static String TAG = "JJWorld.UtilTest";

    private static DecimalFormat df = new DecimalFormat("#.00");

    public static String getPss() {
        // 获取Pss
        Debug.MemoryInfo mi = new Debug.MemoryInfo();
        Debug.getMemoryInfo(mi);
        long memorySize = Debug.getPss();
        // 保留有效数字
        String pssMB = df.format((memorySize / 1024.0));
        return pssMB;
    }

    public static String getPss2() {
        Debug.MemoryInfo mi = new Debug.MemoryInfo();
        Debug.getMemoryInfo(mi);
        int memorySize = mi.getTotalPss();
        return String.format(Locale.US, "%.2f", memorySize/1024.0);
    }


    public static String getPss(Context context){
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        int pid = android.os.Process.myPid();
        int[] pids = new int[]{pid};
        int totalPss = 0;
        try {
            Debug.MemoryInfo[] processMemoryInfo = activityManager.getProcessMemoryInfo(pids);
            for (Debug.MemoryInfo info : processMemoryInfo) {
                totalPss = info.getTotalPss();
            }
        }catch (Exception e) {
            Log.i(TAG, "Exception:" + e.getMessage());
        }
        return String.format(Locale.US, "%.1f", totalPss/1024.0);
    }
}

Debug.MemoryInfo()

测试函数

        costTime = 0;
        index = 1;
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                long startTime = System.currentTimeMillis();
                String pss = getPss2();
                Log.i(TAG, "getPss() pss: " + pss + " cost time:" + (System.currentTimeMillis()- startTime) + " ms");
                costTime = costTime + (System.currentTimeMillis()- startTime);
                if (index % 20 == 0){
                    Log.i(TAG, "costTime: " + (costTime/20));
                    costTime = 0;
                }
                index++;
            }
        }, 0, 1000);

输出

PSS2耗时约为27-28ms。

2023-06-05 17:21:24.812 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 43.16 cost time:18 ms
2023-06-05 17:21:25.814 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 80.00 cost time:20 ms
2023-06-05 17:21:26.821 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 80.08 cost time:27 ms
2023-06-05 17:21:27.824 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 80.08 cost time:28 ms
2023-06-05 17:21:28.824 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 77.97 cost time:26 ms
2023-06-05 17:21:29.824 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.12 cost time:26 ms
2023-06-05 17:21:30.828 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.12 cost time:29 ms
2023-06-05 17:21:31.831 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.13 cost time:31 ms
2023-06-05 17:21:32.832 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.13 cost time:31 ms
2023-06-05 17:21:33.831 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.13 cost time:28 ms
2023-06-05 17:21:34.827 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.13 cost time:24 ms
2023-06-05 17:21:35.828 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.14 cost time:24 ms
2023-06-05 17:21:36.837 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.31 cost time:31 ms
2023-06-05 17:21:37.838 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.94 cost time:30 ms
2023-06-05 17:21:38.839 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.94 cost time:30 ms
2023-06-05 17:21:39.840 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.95 cost time:29 ms
2023-06-05 17:21:40.836 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.95 cost time:23 ms
2023-06-05 17:21:41.845 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.95 cost time:30 ms
2023-06-05 17:21:42.848 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.87 cost time:32 ms
2023-06-05 17:21:43.848 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.87 cost time:31 ms
2023-06-05 17:21:43.848 19176-19729/cn.jj.client I/JJWorld.MainActivity: costTime: 27
2023-06-05 17:21:44.848 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.87 cost time:30 ms
2023-06-05 17:21:45.844 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.87 cost time:25 ms
2023-06-05 17:21:46.854 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.87 cost time:34 ms
2023-06-05 17:21:47.845 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.87 cost time:24 ms
2023-06-05 17:21:48.852 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.88 cost time:30 ms
2023-06-05 17:21:49.855 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.88 cost time:31 ms
2023-06-05 17:21:50.855 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.88 cost time:29 ms
2023-06-05 17:21:51.852 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.89 cost time:24 ms
2023-06-05 17:21:52.862 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.89 cost time:33 ms
2023-06-05 17:21:53.858 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.89 cost time:28 ms
2023-06-05 17:21:54.857 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.89 cost time:26 ms
2023-06-05 17:21:55.863 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.90 cost time:31 ms
2023-06-05 17:21:56.864 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.90 cost time:31 ms
2023-06-05 17:21:57.864 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.90 cost time:30 ms
2023-06-05 17:21:58.861 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.90 cost time:25 ms
2023-06-05 17:21:59.862 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.91 cost time:25 ms
2023-06-05 17:22:00.864 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.91 cost time:26 ms
2023-06-05 17:22:01.868 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.91 cost time:28 ms
2023-06-05 17:22:02.870 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.91 cost time:29 ms
2023-06-05 17:22:03.872 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.91 cost time:29 ms
2023-06-05 17:22:03.872 19176-19729/cn.jj.client I/JJWorld.MainActivity: costTime: 28
2023-06-05 17:22:04.869 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.92 cost time:24 ms
2023-06-05 17:22:05.871 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.92 cost time:24 ms
2023-06-05 17:22:06.876 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.92 cost time:28 ms
2023-06-05 17:22:07.879 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.92 cost time:29 ms
2023-06-05 17:22:08.874 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.92 cost time:23 ms
2023-06-05 17:22:09.876 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.92 cost time:24 ms
2023-06-05 17:22:10.886 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.93 cost time:32 ms
2023-06-05 17:22:11.882 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.93 cost time:27 ms
2023-06-05 17:22:12.884 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.93 cost time:28 ms
2023-06-05 17:22:13.887 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.94 cost time:29 ms
2023-06-05 17:22:14.882 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.94 cost time:23 ms
2023-06-05 17:22:15.882 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.94 cost time:22 ms
2023-06-05 17:22:16.886 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.94 cost time:24 ms
2023-06-05 17:22:17.889 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.94 cost time:26 ms
2023-06-05 17:22:18.896 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.94 cost time:31 ms
2023-06-05 17:22:19.892 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.95 cost time:25 ms
2023-06-05 17:22:20.901 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.95 cost time:31 ms
2023-06-05 17:22:21.902 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.95 cost time:31 ms
2023-06-05 17:22:22.902 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.96 cost time:29 ms
2023-06-05 17:22:23.904 19176-19729/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 73.96 cost time:29 ms
2023-06-05 17:22:23.904 19176-19729/cn.jj.client I/JJWorld.MainActivity: costTime: 27

测试函数2

        costTime = 0;
        index = 1;
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                long startTime = System.currentTimeMillis();
                String pss = getPss();
                Log.i(TAG, "getPss() pss: " + pss + " cost time:" + (System.currentTimeMillis()- startTime) + " ms");
                costTime = costTime + (System.currentTimeMillis()- startTime);
                if (index % 20 == 0){
                    Log.i(TAG, "costTime: " + (costTime/20));
                    costTime = 0;
                }
                index++;
            }
        }, 0, 1000);

输出

PSS耗时约为33-35ms。

2023-06-05 17:25:26.935 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 43.88 cost time:27 ms
2023-06-05 17:25:27.930 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 80.26 cost time:21 ms
2023-06-05 17:25:28.956 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 80.34 cost time:47 ms
2023-06-05 17:25:29.963 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.24 cost time:53 ms
2023-06-05 17:25:30.949 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.24 cost time:38 ms
2023-06-05 17:25:31.955 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.40 cost time:43 ms
2023-06-05 17:25:32.952 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.41 cost time:37 ms
2023-06-05 17:25:33.950 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.41 cost time:33 ms
2023-06-05 17:25:34.952 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.41 cost time:34 ms
2023-06-05 17:25:35.956 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.41 cost time:36 ms
2023-06-05 17:25:36.960 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.41 cost time:38 ms
2023-06-05 17:25:37.955 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.42 cost time:32 ms
2023-06-05 17:25:38.953 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.42 cost time:29 ms
2023-06-05 17:25:39.957 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.42 cost time:31 ms
2023-06-05 17:25:40.965 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 78.42 cost time:38 ms
2023-06-05 17:25:41.967 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.17 cost time:38 ms
2023-06-05 17:25:42.966 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.17 cost time:36 ms
2023-06-05 17:25:43.967 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.18 cost time:36 ms
2023-06-05 17:25:44.964 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.18 cost time:32 ms
2023-06-05 17:25:45.971 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.18 cost time:38 ms
2023-06-05 17:25:45.971 19578-20563/cn.jj.client I/JJWorld.MainActivity: costTime: 35
2023-06-05 17:25:46.973 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.10 cost time:39 ms
2023-06-05 17:25:47.975 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.10 cost time:39 ms
2023-06-05 17:25:48.973 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.10 cost time:36 ms
2023-06-05 17:25:49.975 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.10 cost time:36 ms
2023-06-05 17:25:50.969 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.10 cost time:29 ms
2023-06-05 17:25:51.972 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.10 cost time:30 ms
2023-06-05 17:25:52.982 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.11 cost time:39 ms
2023-06-05 17:25:53.979 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.11 cost time:35 ms
2023-06-05 17:25:54.984 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.11 cost time:39 ms
2023-06-05 17:25:55.982 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.12 cost time:36 ms
2023-06-05 17:25:56.983 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.12 cost time:36 ms
2023-06-05 17:25:57.981 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.09 cost time:31 ms
2023-06-05 17:25:58.988 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.09 cost time:35 ms
2023-06-05 17:25:59.989 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.10 cost time:35 ms
2023-06-05 17:26:00.990 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.10 cost time:35 ms
2023-06-05 17:26:01.989 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.10 cost time:33 ms
2023-06-05 17:26:02.994 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.10 cost time:35 ms
2023-06-05 17:26:03.990 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.10 cost time:31 ms
2023-06-05 17:26:04.996 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.11 cost time:35 ms
2023-06-05 17:26:05.999 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.11 cost time:37 ms
2023-06-05 17:26:05.999 19578-20563/cn.jj.client I/JJWorld.MainActivity: costTime: 35
2023-06-05 17:26:06.994 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.11 cost time:31 ms
2023-06-05 17:26:07.997 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.11 cost time:32 ms
2023-06-05 17:26:09.005 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.12 cost time:38 ms
2023-06-05 17:26:10.006 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.12 cost time:38 ms
2023-06-05 17:26:11.007 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.12 cost time:38 ms
2023-06-05 17:26:12.008 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.12 cost time:37 ms
2023-06-05 17:26:13.002 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.12 cost time:30 ms
2023-06-05 17:26:14.003 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.13 cost time:29 ms
2023-06-05 17:26:15.005 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.13 cost time:30 ms
2023-06-05 17:26:16.011 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.13 cost time:33 ms
2023-06-05 17:26:17.015 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.13 cost time:36 ms
2023-06-05 17:26:18.011 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.14 cost time:30 ms
2023-06-05 17:26:19.020 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.14 cost time:38 ms
2023-06-05 17:26:20.021 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.14 cost time:37 ms
2023-06-05 17:26:21.023 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.14 cost time:37 ms
2023-06-05 17:26:22.018 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.14 cost time:30 ms
2023-06-05 17:26:23.017 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.15 cost time:28 ms
2023-06-05 17:26:24.021 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.15 cost time:31 ms
2023-06-05 17:26:25.029 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.15 cost time:37 ms
2023-06-05 17:26:26.030 19578-20563/cn.jj.client I/JJWorld.MainActivity: getPss() pss: 74.15 cost time:35 ms
2023-06-05 17:26:26.030 19578-20563/cn.jj.client I/JJWorld.MainActivity: costTime: 33

电池

Android系统中,一些广播是属于系统级别的广播,不需要应用程序申请权限即可接收。其中,Intent.ACTION_BATTERY_CHANGED广播就是一个系统级别的广播,用于向所有注册了该广播的应用程序提供电池电量信息。因此,应用程序可以通过注册该广播来获取电池电量信息,而不需要申请任何权限。

电池容量

此方法通过反射获取电池容量,

    public static String getBatteryCapacity(Context context) {
        Object mPowerProfile;
        double batteryCapacity = 0;
        final String POWER_PROFILE_CLASS = "com.android.internal.os.PowerProfile";

        try {
            mPowerProfile = Class.forName(POWER_PROFILE_CLASS)
                    .getConstructor(Context.class)
                    .newInstance(context);

            batteryCapacity = (double) Class
                    .forName(POWER_PROFILE_CLASS)
                    .getMethod("getBatteryCapacity")
                    .invoke(mPowerProfile);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return String.valueOf(batteryCapacity + " mAh");
    }

使用了Android隐藏的方法,因此会提示Accessing hidden method 。

2023-04-07 11:31:04.514 18264-19505/cn.jj.jjapmsdk W/cn.jj.jjapmsdk: Accessing hidden method Lcom/android/internal/os/PowerProfile;-><init>(Landroid/content/Context;)V (unsupported, reflection, allowed)
2023-04-07 11:31:04.522 18264-19505/cn.jj.jjapmsdk W/cn.jj.jjapmsdk: Accessing hidden method Lcom/android/internal/os/PowerProfile;->getBatteryCapacity()D (unsupported, reflection, allowed)

UI界面卡顿

基础概念:

  • VSYNC(垂直刷新/绘制)

VSYNC:有两个概念:
1)Refresh Rate: 屏幕在一秒内的刷新次数 — 由硬件的参数决定 60Hz 刷新频率
2)Frame Rate:帧频率。GPU在一秒内绘制的帧数。比如 60fps

  • GPU刷新

GPU帮助我们将UI组件等计算成纹理。

单应用可用的最大内存

dalvik.vm.heapstartsize,表示堆分配的初始大小。
dalvik.vm.heapgrowthlimit,表示单个进程的内存限定值。
dalvik.vm.heapsize,表示单个进程的内存限定值。
默认情况下,android以dalvik.vm.heapgrowthlimit作为单个进程的最大内存,如果想要使用dalvik.vm.heapsize,需要在manifest中声明

android:largeHeap = true

查看内存大小可以使用adb指令。

adb shell getprop dalvik.vm.heapstartsize

红米K50中此值为8M

OOM是否能够捕获

OOM属于ERROR
IO EXCEPTION属于EXCEPTION
OOM可以捕获,但是不能通过EXCEPTION捕获
示例:

public class ExampleUnitTest {
    private static final String TAG = "JJWorld";

    @Test
    public void addition_isCorrect() {
        try {
            ArrayList<Integer> list = new ArrayList<>();
            int i = 0;
            while (true){
                list.add(i++);
            }
        }catch (Exception e){
            Log.e(TAG, "Exception: " + e.getMessage());
        }
        Log.e(TAG, "message after OOM!");
    }
}

输出:

Java heap space
java.lang.OutOfMemoryError: Java heap space
	at java.base/java.util.Arrays.copyOf(Arrays.java:3689)
	at java.base/java.util.ArrayList.grow(ArrayList.java:238)
	at java.base/java.util.ArrayList.grow(ArrayList.java:243)
	at java.base/java.util.ArrayList.add(ArrayList.java:486)
	at java.base/java.util.ArrayList.add(ArrayList.java:499)
	at com.example.interfacebackstudy.ExampleUnitTest.addition_isCorrect(ExampleUnitTest.java:25)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

将Exception改为Error:

public class ExampleUnitTest {
    private static final String TAG = "JJWorld";

    @Test
    public void addition_isCorrect() {
        try {
            ArrayList<Integer> list = new ArrayList<>();
            int i = 0;
            while (true){
                list.add(i++);
            }
        }catch (Error e){
            System.out.println("OOM:" + e.getMessage());
        }
        System.out.println("After OOM");
    }
}

输出结果如下:

> Task :app:testDebugUnitTest
OOM:Java heap space
After OOM
BUILD SUCCESSFUL in 3s
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
赵子健是知名的 Android 专家,他在性能优化方面也有很多经验。以下是他在 Android 性能优化方面的一些建议: 1. 减少内存分配:内存分配是 Android 应用程序中的一个性能瓶颈,过多的内存分配会导致频繁的垃圾回收和系统卡顿。因此,应该尽量减少内存分配,比如使用对象池、避免频繁的创建和销毁对象等。 2. 使用异步任务:在 Android 应用程序中,如果主线程(UI 线程)执行耗时操作,会导致应用程序卡顿或者 ANR。因此,应该使用异步任务来执行耗时操作,比如使用 AsyncTask、HandlerThread、ThreadPoolExecutor 等。 3. 优化布局:布局也是 Android 应用程序中的一个性能瓶颈,过于复杂的布局会导致 UI 渲染变慢,甚至卡顿。因此,应该尽量简化布局,避免嵌套过深、避免不必要的布局文件等。 4. 避免过度绘制:Android 应用程序中的另一个性能瓶颈是过度绘制。过度绘制是指在同一个区域内反复绘制,导致不必要的 CPU 和 GPU 资源消耗。因此,应该避免过度绘制,比如使用 setWillNotDraw() 方法、使用硬件加速等。 5. 使用工具进行优化:Android 中有很多性能优化工具,比如 TraceView、Systrace、HierarchyViewer 等,可以帮助开发者找到应用程序中的性能瓶颈,进行优化。 以上是赵子健在 Android 性能优化方面的一些建议,当然还有很多其他的优化技巧和工具,需要根据实际情况进行选择和应用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学知识拯救世界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值