Android性能优化第(七)篇---StrickMode严苛模式检测耗时与内存问题

本文主要是介绍Android性能优化第(七)篇---StrickMode严苛模式检测耗时与内存问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

StrictMode意思为严格模式,是用来检测程序中违例情况的开发者工具。使用一般是场景是检测主线程中本地磁盘和网络读写等耗时的操作。注意这个StrictMode是在Anroid2.3以后引入的。严格模式主要检测两大问题,一个是线程策略,即TreadPolicy,另一个是VM策略,即VmPolicy。

线程策略(ThreadPolicy)检测的内容有

  • 1、自定义的耗时调用 使用detectCustomSlowCalls()开启
  • 2、磁盘读取操作 使用detectDiskReads()开启
  • 3、磁盘写入操作 使用detectDiskWrites()开启
  • 4、网络操作 使用detectNetwork()开启

虚拟机策略(VmPolicy)检测的内容有

  • 1、Activity泄露 使用detectActivityLeaks()开启
  • 2、未关闭的Closable对象泄露 使用detectLeakedClosableObjects()开启
  • 3、泄露的Sqlite对象 使用detectLeakedSqlLiteObjects()开启
  • 4、检测实例数量 使用setClassInstanceLimit()开启

可以看到线程策略主要与异步处理相关,虚拟机策略主要与内存管理相关。setThreadPolicy()将对当前线程应用该策略。如果不指定检测函数,也可以用detectAll()来替代。penaltyLog()表示将警告输出到LogCat,你也可以使用其他或增加新的惩罚(penalty)函数,例如使用penaltyDeath()的话,一旦StrictMode消息被写到LogCat后应用就会崩溃。另外虚拟机策略(VmPolicy)不能通过一个对话框提供警告。

在线程策略(ThreadPolicy)检测的时候,有几个penalty系列方法。

  • 1、penaltyDeath(),当触发违规条件时,直接Crash掉当前应用程序。
  • 2、penaltyDeathOnNetwork(),当触发网络违规时,Crash掉当前应用程序。
  • 3、penaltyDialog(),触发违规时,显示对违规信息对话框。
  • 4、penaltyFlashScreen(),会造成屏幕闪烁,不过一般的设备可能没有这个功能。

如何使用严格模式

严格模式的开启可以放在Application或者Activity以及其他组件的onCreate方法。为了更好地分析应用中的问题,建议放在Application的onCreate方法中。设置一次就够了。

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll()//开启所有的detectXX系列方法.penaltyDialog()//弹出违规提示框.penaltyLog()//在Logcat中打印违规日志.build());requestDataFromNet();}/*** 请求数据*/private void requestDataFromNet() {URL url;try {url = new URL("http://www.baidu.com");HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.connect();BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));String lines ;StringBuilder sb = new StringBuilder();while ((lines = reader.readLine()) != null) {sb.append(lines);}Log.d("response",sb.toString());} catch (Exception e) {e.printStackTrace();}}
}

比如上面代码运行之后,就会有下面的弹窗出来警告。 

看一下logcat的日志,是在主线程中做了访问网络的操作。

12-19 17:28:54.226 2729-2729/? D/StrictMode: StrictMode policy violation; ~duration=44 ms: android.os.StrictMode$StrictModeNetworkViolation: policy=63 violation=4at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1123)at java.net.InetAddress.lookupHostByName(InetAddress.java:385)at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)at java.net.InetAddress.getAllByName(InetAddress.java:214)at libcore.net.http.HttpConnection.<init>(HttpConnection.java:70)at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:340)at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87)at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:316)at libcore.net.http.HttpEngine.connect(HttpEngine.java:311)at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:81)at zhangwan.wj.com.myshare.MainActivity.requestDataFromNet(MainActivity.java:35)at zhangwan.wj.com.myshare.MainActivity.onCreate(MainActivity.java:27)at android.app.Activity.performCreate(Activity.java:5104)at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1092)at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2254)at android.app.ActivityThread.access$600(ActivityThread.java:141)at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)at android.os.Handler.dispatchMessage(Handler.java:99)at android.os.Looper.loop(Looper.java:137)at android.app.ActivityThread.main(ActivityThread.java:5069)at java.lang.reflect.Method.invokeNative(Native Method)at java.lang.reflect.Method.invoke(Method.java:511)at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)at dalvik.system.NativeStart.main(Native Method)

上面分析了是异步处理相关的例子,现在分析一个内存管相关的例子,比如检测内存泄露检测,用StrickMode怎么搞?

 public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectActivityLeaks()//检测Activity泄露.penaltyLog()//在Logcat中打印违规日志.build());UserManger instance = UserManger.getInstance(this);}}

比如上面的代码UserManger持有了Activity的引用,当反复进入Activity的时候,Activity不能被回收,导致了内存泄露,此时看Logcat。

12-20 09:57:07.626 4787-4787/? E/StrictMode: class zhangwan.wj.com.myshare.MainActivity; instances=3; limit=1android.os.StrictMode$InstanceCountViolation: class zhangwan.wj.com.myshare.MainActivity; instances=3; limit=1at android.os.StrictMode.setClassInstanceLimit(StrictMode.java:1)

明确告诉我们instances=3,说明泄露了3个MainActivity对象

严格模式除了可以检测Activity的内存泄露之外,还能自定义检测类的对象泄露。这个从从API 11 开始。

public
StrictMode.VmPolicy.Builder setClassInstanceLimit (Class klass, int instanceLimit)

比如,检测UserManger有没有泄露,可以这么写。

StrictMode.setVmPolicy(new VmPolicy.Builder().setClassInstanceLimit(UserManger.class, 1).penaltyLog().build());

在比如detectLeakedClosableObjects() 和 detectLeakedSqlLiteObjects(),资源没有正确关闭时回触发,detectLeakedRegistrationObjects() 用来检查 BroadcastReceiver 或者 ServiceConnection 注册类对象是否被正确释放等。

StrictMode有个更直接的办法,在部分手机上,可以在开发者选项中开启严格模式,开启之后,如果主线程中有执行时间长的操作,屏幕则会闪烁。OKStrictMode比较简单,到此结束!

这篇关于Android性能优化第(七)篇---StrickMode严苛模式检测耗时与内存问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/755140

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

NameNode内存生产配置

Hadoop2.x 系列,配置 NameNode 内存 NameNode 内存默认 2000m ,如果服务器内存 4G , NameNode 内存可以配置 3g 。在 hadoop-env.sh 文件中配置如下。 HADOOP_NAMENODE_OPTS=-Xmx3072m Hadoop3.x 系列,配置 Nam

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo