Android内存泄露分析之StrictMode
转载请注明地址:http://blog.csdn.NET/yincheng886337/article/details/50524709
StrictMode(严格模式)使用
StrictMode严格模式,主要用来检测程序中违例情况的开发者工具。最常用的场景就是检测主线程中本地磁盘、网络读写等耗时的操作以及Activity泄露等,但该模式不建议在Release版本开启,此外该模式无法监控JNI中的磁盘IO和网络请求且其违例情况仅供参考,需结合实际开发需求予以解决。
StrictMode检测什么?
主要采用采用ThreadPolicy(线程策略)和VmPolicy(Vm策略)进行检测,各策略检测内容如下:
ThreadPolicy
线程策略检测的内容有
· 自定义的耗时调用 使用 detectCustomSlowCalls() 开启
· 磁盘读取操作 使用 detectDiskReads() 开启
· 磁盘写入操作 使用 detectDiskWrites() 开启
· 网络操作 使用 detectNetwork() 开启
VmPolicy
虚拟机策略检测的内容有
· Activity泄露 使用 detectActivityLeaks() 开启
· 未关闭的Closable对象泄露 使用 detectLeakedClosableObjects() 开启
· 泄露的Sqlite对象 使用 detectLeakedSqlLiteObjects() 开启
· 检测实例数量 使用 setClassInstanceLimit() 开启
StrictMode具体使用
public class DebugUtil {
public static void startStrictModeVmPolicy(){
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectActivityLeaks()/*检测Activity内存泄露*/
.detectLeakedClosableObjects()/*检测未关闭的Closable对象*/
.detectLeakedSqlLiteObjects() /*检测Sqlite对象是否关闭*/
/*也可以采用detectAll()来检测所有想检测的东西*/
.penaltyLog().build());
}
public static void startStrictModeThreadPolicy(){
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()/*磁盘读取操作检测*/
.detectDiskWrites()/*检测磁盘写入操作*/
.detectNetwork() /*检测网络操作*/
/*也可以采用detectAll()来检测所有想检测的东西*/
.penaltyLog().build());
}
}
如果你想检测整个App或某Activity的相关泄露问题,可在Application或Activity的onCreate方法中直接调用DebugUtil中封装好的策略即可
如何查看检测结果?
只需要查看TAG为StrictMode的日志即可,如:logcat -c;logcat -s StrictMode 或者adb logcat | grep StrictMode
如何解决检测出来的问题?
针对此问题下面给出几点建议,仅供参考:
1.如果是主线程中出现文件读写违例问题,建议使用工作线程(可采用HandlerThread,IntentService、线程池或直接new Thread,必要时可结合Handler)完成,但采用工作线程在某个Activity中操作时注意线程要能正常结束,否则将导致内存泄露,相关细节后文将有表述。
2.如果是对SharedPrefrences写入操作,在API 9以上建议优先调用apply而非commit,此外需注意的是确保SharedPrefrences在单进程中使用,如果涉及跨进程数据交换,建议自己编写跨进程SharedPrefrences实现机制,否则可能导致数据不准确。
3.如果存在未关闭的Closable对象,需根据对应的stacktrace进行关闭。
4.如果SQLite对象泄露,根据对应的stacktrace进行释放。
5.注意registerBroadcast和unregisterBroadcast配对使用,对文件操作完成后记得close操作。
StrictMode使用示例
现以主线程中文件读写为例,引起违例警告的代码如下:
public void writeToExternalStorage() {
File externalStorage = Environment.getExternalStorageDirectory();
File destFile = new File(externalStorage, "dest.txt");
try {
OutputStream output = new FileOutputStream(destFile, true);
output.write("droidyue.com".getBytes());
output.flush();
output.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
StrictMode违例警告:
D/StrictMode( ): StrictMode policy violation; ~duration= ms: android.os.StrictMode$StrictModeDiskReadViolation: policy= violation=
D/StrictMode( ): at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:)
D/StrictMode( ): at libcore.io.BlockGuardOs.open(BlockGuardOs.java:)
D/StrictMode( ): at libcore.io.IoBridge.open(IoBridge.java:)
D/StrictMode( ): at java.io.FileOutputStream.<init>(FileOutputStream.java:)
D/StrictMode( ): at com.example.strictmodedemo.MainActivity.writeToExternalStorage(MainActivity.java:)
D/StrictMode( ): at com.example.strictmodedemo.MainActivity.onCreate(MainActivity.java:)
D/StrictMode( ): at android.app.Activity.performCreate(Activity.java:)
解决方法:
public void writeToExternalStorage() {
new Thread(){
@Override
public void run() {
/*将对读写操作移至线程*/
File externalStorage = Environment.getExternalStorageDirectory();
File destFile = new File(externalStorage, "dest.txt");
OutputStream output = null;
try {
output = new FileOutputStream(destFile, true);
output.write("droidyue.com".getBytes());
output.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
/*对文件操作完成后,注意关闭*/
if(output != null){
output.close();
}
}
}
}
}
Android内存泄露分析之StrictMode的更多相关文章
- JVM内存管理概述与android内存泄露分析
一.内存划分 将内存划分为六大部分,分别是PC寄存器.JAVA虚拟机栈.JAVA堆.方法区.运行时常量池以及本地方法栈. 1.PC寄存器(线程独有):全称是程序计数寄存器,它记载着每一个线程当前运行的 ...
- (转)专项:Android 内存泄露实践分析
今天看到一篇关于Android 内存泄露实践分析的文章,感觉不错,讲的还算详细,mark到这里. 原文发表于:Testerhome: 作者:ycwdaaaa ; 原文链接:https://teste ...
- Android Studio 使用Memory Monitor进行内存泄露分析
在使用Android Studio进行内存泄露分析之前,我们先回顾一下Java相关的内存管理机制,然后再讲述一下内存分析工具如何使用. 一.Java内存管理机制 1. Java内存分配策略 Java ...
- Android内存机制分析1——了解Android堆和栈
//----------------------------------------------------------------------------------- Android内存机制分析1 ...
- Android 内存泄漏分析与解决方法
在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...
- Android内存机制分析2——分析APP内存使用情况
上面一篇文章说了Android应用运行在dalvik里面分配的堆和栈内存区别,以及程序中什么代码会在哪里运行.今天主要是讲解一下Android里面如何分析我们程序内存使用情况.以便后续可以分析我们程序 ...
- Android内存泄露调试
Android 内存泄漏调试 一.概述 如果我们编写的代码当中有太多的对内存使用不当的地方,难免会使得我们的设备运行缓慢,甚至是死机.为了能够使得 Android 应用程序安全且快速的运行, Andr ...
- 关于内存泄露分析插件 MAT 的用法
关于内存泄露分析插件 MAT 的用法,建议大家有时间看一下,下面的文章 http://www.blogjava.net/rosen/archive/2010/05/21/321575.html htt ...
- Android 内存管理分析(四)
尊重原创作者,转载请注明出处: http://blog.csdn.net/gemmem/article/details/8920039 最近在网上看了不少Android内存管理方面的博文,但是文章大多 ...
随机推荐
- sql的四大函数
字符串函数: 1.charindex(字符串表达式 1, 字符串表达式2[,整数表达式]) select charindex('ab','BCabTabD')返回 3 select charindex ...
- Java main方法中的String[] args
-- Java 命令行参数 -- 关于其中的args以及public static / static public Java 命令行参数 前面已经看到多个使用Java数组的示例,每一个Java应用程序 ...
- php, hhvm与odp & Unix domain Socket方式
接上一篇,复习一下 启动php或hhvm: php/sbin/php-fpm start hhvm/bin/hhvm_control start 启动nginx或lighttpd: webserver ...
- android 4.4最新官方源代码下载
国内网络,日夜不休花了一个多月才下载成功android标准源代码,有些开发同人须要.已上传到网盘,分享给大家 微云地址: http://url.cn/PkkSzC 百度云盘地址(更新) http:// ...
- Android基础新手教程——1.2.1 使用Eclipse + ADT + SDK开发Android APP
Android基础新手教程--1.2.1 使用Eclipse + ADT + SDK开发Android APP 标签(空格分隔): Android基础新手教程 1.前言 这里我们有两条路能够选,直接使 ...
- 【BUG】"main" prio=5 tid=1 RUNNABLE
载入超大效果图导致内存不足(GC/ANR) 06-30 11:42:56.624: D/dalvikvm(16264): GC_CONCURRENT freed 1982K, 7% free 4537 ...
- nagios,zabbix对照
nagios/zabbix对照: nagios核心功能是监控报警.是一个轻量化的监控系统. 假设须要图标显示,须要添加图标显示插件(如pnp4nagios): 假设须要存入数据库,须要对应的插件(ND ...
- jQuery08源码 (5140 , 6057) DOM操作 : 添加 删除 获取 包装 DOM筛选
jQuery.fn.extend({ //$('ul').find('li').css('background','red'); //$('ul').find( $('li') ).css('back ...
- 虚拟局域网(VLAN)技术在企业网管理中的应用
虚拟局域网(VLAN)技术在企业网管理中的应用 1.VLAN介绍 所谓VLAN 是指处于不同物理位置的节点根据需要组成不同的逻辑子网,即一个VLAN 就是一个逻辑广播域,它可以覆盖多个网络设备 ...
- Linux系统存储交换机日志
Linux系统存储交换机日志 日志记录是为系统设备在运行过程中报告其运行情况而设的, 为了保证系统正常运行, 解决每一天可能遇到的各种各样的问题, 网络管理员必须认真地读取日志记录.目前公司系 ...