最近做一个android 的应用程序 总是出现内存高 和cpu高的问题困扰了好多天。

下面为自己从网上总结的和自己找到的问题。

1. WebView  控件:

使用了 WebView 控件一定要注意清理缓存  destroy() 方法,但之前必须调用 removeAllViews() 要不然有时出错

1 myWebView.removeAllViews();
2 myWebView.destroy();

2.线程

在退出活动窗口时一定要注意开启的线程是否已经关闭,可以在debug查看线程的开启情况。

如果只是刷新Ui线程 建议不用线程可以使用 Handler 来刷新 方法如下。这种方法只能做简单的操作,复杂操作建议使用线程。

01 private Handler
_ui_handler = 
new Handler()
{
02  
03     @Override
04     public void handleMessage(Message
msg) {
05  
06     switch (msg.what)
{
07         case 0://下面你可以写你需要处理的代码
08                 _ui_handler
.sendEmptyMessageDelayed(
0,1000)//1000
为延时发送的时间 单位是毫秒
09         break;
10         }
11     }
12 }

3 sqlite

使用sqlite是一定要注意 关闭当前指针 和数据库连接

下面为注意内存溢出的问题

http://rayleeya.iteye.com/blog/727074

各位兄弟姐妹,Java开发中的内存泄露的问题经常会给我们带来很多烦恼。特别是对一些新手,如果平时不注意一些细节问题,最后很可能会导致很严重的后果。

在Android中的Java开发也同样会有这样的问题。附件中的pdf整理了一些关于Android中的Java开发,在内存使用方面需要注意的一些问题,希望能够对大家有所帮助。

接下篇: [Android] 内存泄漏调试经验分享 (二) http://rayleeya.iteye.com/blog/755657

Android 内存泄漏调试

Made by 李文栋

liwd@thunderst.com | rayleeya@gmail.com

2010-07-25  Friday

一、概述 1

二、Android(Java)中常见的容易引起内存泄漏的不良代码 1

(一) 查询数据库没有关闭游标 2

(二) 构造Adapter时,没有使用缓存的 convertView 3

(三) Bitmap对象不在使用时调用recycle()释放内存 4

(四) 释放对象的引用 4

(五) 其他 5

三、内存监测工具 DDMS --> Heap 5

四、内存分析工具 MAT(Memory Analyzer Tool) 7

(一) 生成.hprof文件 7

(二) 使用MAT导入.hprof文件 8

(三) 使用MAT的视图工具分析内存 8

一、概述

Java编程中经常容易被忽视,但本身又十分重要的一个问题就是内存使用的问题。Android应用主要使用Java语言编写,因此这个问题也同样会在Android开发中出现。本文不对Java编程问题做探讨,而是对于在Android中,特别是应用开发中的此类问题进行整理。

由于作者接触Android时间并不是很长,因此如有叙述不当之处,欢迎指正。

二、Android(Java)中常见的容易引起内存泄漏的不良代码

Android主要应用在嵌入式设备当中,而嵌入式设备由于一些众所周知的条件限制,通常都不会有很高的配置,特别是内存是比较有限的。如果我们编写的代码当中有太多的对内存使用不当的地方,难免会使得我们的设备运行缓慢,甚至是死机。为了能够使得Android应用程序安全且快速的运行,Android的每个应用程序都会使用一个专有的Dalvik虚拟机实例来运行,它是由Zygote服务进程孵化出来的,也就是说每个应用程序都是在属于自己的进程中运行的。一方面,如果程序在运行过程中出现了内存泄漏的问题,仅仅会使得自己的进程被kill掉,而不会影响其他进程(如果是system_process等系统进程出问题的话,则会引起系统重启)。另一方面Android为不同类型的进程分配了不同的内存使用上限,如果应用进程使用的内存超过了这个上限,则会被系统视为内存泄漏,从而被kill掉。Android为应用进程分配的内存上限如下所示:

位置: /ANDROID_SOURCE/system/core/rootdir/init.rc 部分脚本

# Define the oom_adj values for the classes of processes that can be

# killed by the kernel.  These are used in ActivityManagerService.

setprop ro.FOREGROUND_APP_ADJ 0

setprop ro.VISIBLE_APP_ADJ 1

setprop ro.SECONDARY_SERVER_ADJ 2

setprop ro.BACKUP_APP_ADJ 2

setprop ro.HOME_APP_ADJ 4

setprop ro.HIDDEN_APP_MIN_ADJ 7

setprop ro.CONTENT_PROVIDER_ADJ 14

setprop ro.EMPTY_APP_ADJ 15

# Define the memory thresholds at which the above process classes will

# be killed.  These numbers are in pages (4k).

setprop ro.FOREGROUND_APP_MEM 1536

setprop ro.VISIBLE_APP_MEM 2048

setprop ro.SECONDARY_SERVER_MEM 4096

setprop ro.BACKUP_APP_MEM 4096

setprop ro.HOME_APP_MEM 4096

setprop ro.HIDDEN_APP_MEM 5120

setprop ro.CONTENT_PROVIDER_MEM 5632

setprop ro.EMPTY_APP_MEM 6144

# Write value must be consistent with the above properties.

# Note that the driver only supports 6 slots, so we have HOME_APP at the

# same memory level as services.

write /sys/module/lowmemorykiller/parameters/adj 0,1,2,7,14,15

write /proc/sys/vm/overcommit_memory 1

write /proc/sys/vm/min_free_order_shift 4

write /sys/module/lowmemorykiller/parameters/minfree 1536,2048,4096,5120,5632,6144

# Set init its forked children's oom_adj.

write /proc/1/oom_adj -16

正因为我们的应用程序能够使用的内存有限,所以在编写代码的时候需要特别注意内存使用问题。如下是一些常见的内存使用不当的情况。

(一) 查询数据库没有关闭游标

描述:

程序中经常会进行查询数据库的操作,但是经常会有使用完毕Cursor后没有关闭的情况。如果我们的查询结果集比较小,对内存的消耗不容易被发现,只有在常时间大量操作的情况下才会复现内存问题,这样就会给以后的测试和问题排查带来困难和风险。

示例代码:

Cursor cursor = getContentResolver().query(uri ...);

if (cursor.moveToNext()) {

... ...

}

修正示例代码:

Cursor cursor = null;

try {

cursor = getContentResolver().query(uri ...);

if (cursor != null && cursor.moveToNext()) {

... ...

}

} finally {

if (cursor != null) {

try {

cursor.close();

} catch (Exception e) {

//ignore this

}

}

}

(二) 构造Adapter时,没有使用缓存的 convertView

描述:

以构造ListView的BaseAdapter为例,在BaseAdapter中提高了方法:

public View getView(int position, View convertView, ViewGroup parent)

来向ListView提供每一个item所需要的view对象。初始时ListView会从BaseAdapter中根据当前的屏幕布局实例化一定数量的view对象,同时ListView会将这些view对象缓存起来。当向上滚动ListView时,原先位于最上面的list item的view对象会被回收,然后被用来构造新出现的最下面的list item。这个构造过程就是由getView()方法完成的,getView()的第二个形参 View convertView就是被缓存起来的list item的view对象(初始化时缓存中没有view对象则convertView是null)。

由此可以看出,如果我们不去使用convertView,而是每次都在getView()中重新实例化一个View对象的话,即浪费资源也浪费时间,也会使得内存占用越来越大。ListView回收list item的view对象的过程可以查看:

android.widget.AbsListView.java --> void addScrapView(View scrap) 方法。

示例代码:

public View getView(int position, View convertView, ViewGroup parent) {

View view = new Xxx(...);

... ...

return view;

}

修正示例代码:

public View getView(int position, View convertView, ViewGroup parent) {

View view = null;

if (convertView != null) {

view = convertView;

populate(view, getItem(position));

...

} else {

view = new Xxx(...);

...

}

return view;

}

(三) Bitmap对象不在使用时调用recycle()释放内存

描述:

有时我们会手工的操作Bitmap对象,如果一个Bitmap对象比较占内存,当它不在被使用的时候,可以调用Bitmap.recycle()方法回收此对象的像素所占用的内存,但这不是必须的,视情况而定。可以看一下代码中的注释:

/**

* Free up the memory associated with this bitmap's pixels, and mark the

* bitmap as "dead", meaning it will throw an exception if getPixels() or

* setPixels() is called, and will draw nothing. This operation cannot be

* reversed, so it should only be called if you are sure there are no

* further uses for the bitmap. This is an advanced call, and normally need

* not be called, since the normal GC process will free up this memory when

* there are no more references to this bitmap.

*/

(四) 释放对象的引用

描述:

这种情况描述起来比较麻烦,举两个例子进行说明。

示例A:

假设有如下操作

public class DemoActivity extends Activity {

... ...

private Handler mHandler = ...

private Object obj;

public void operation() {

obj = initObj();

...

[Mark]

mHandler.post(new Runnable() {

public void run() {

useObj(obj);

}

});

}

}

我们有一个成员变量 obj,在operation()中我们希望能够将处理obj实例的操作post到某个线程的MessageQueue中。在以上的代码中,即便是mHandler所在的线程使用完了obj所引用的对象,但这个对象仍然不会被垃圾回收掉,因为DemoActivity.obj还保有这个对象的引用。所以如果在DemoActivity中不再使用这个对象了,可以在[Mark]的位置释放对象的引用,而代码可以修改为:

... ...

public void operation() {

obj = initObj();

...

final Object o = obj;

obj = null;

mHandler.post(new Runnable() {

public void run() {

useObj(o);

}

}

}

... ...

示例B:

假设我们希望在锁屏界面(LockScreen)中,监听系统中的电话服务以获取一些信息(如信号强度等),则可以在LockScreen中定义一个PhoneStateListener的对象,同时将它注册到TelephonyManager服务中。对于LockScreen对象,当需要显示锁屏界面的时候就会创建一个LockScreen对象,而当锁屏界面消失的时候LockScreen对象就会被释放掉。

但是如果在释放LockScreen对象的时候忘记取消我们之前注册的PhoneStateListener对象,则会导致LockScreen无法被垃圾回收。如果不断的使锁屏界面显示和消失,则最终会由于大量的LockScreen对象没有办法被回收而引起OutOfMemory,使得system_process进程挂掉。

总之当一个生命周期较短的对象A,被一个生命周期较长的对象B保有其引用的情况下,在A的生命周期结束时,要在B中清除掉对A的引用。

(五) 其他

Android应用程序中最典型的需要注意释放资源的情况是在Activity的生命周期中,在onPause()、onStop()、onDestroy()方法中需要适当的释放资源的情况。由于此情况很基础,在此不详细说明,具体可以查看官方文档对Activity生命周期的介绍,以明确何时应该释放哪些资源

android 内存优化 性能优化的更多相关文章

  1. 转——Android应用开发性能优化完全分析

    [工匠若水 http://blog.csdn.net/yanbober 转载请注明出处.] 1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉 ...

  2. Android 应用开发性能优化完全分析

    1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉大家你一总结.我一总结的都说到了很多优化注意事项,但是看过这些文章后大多数存在一个问题就是只 ...

  3. 【转】Android应用开发性能优化完全分析

    http://blog.csdn.net/yanbober/article/details/48394201 1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关 ...

  4. Android应用开发性能优化完全分析

    1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉大家你一总结.我一总结的都说到了很多优化注意事项,但是看过这些文章后大多数存在一个问题就是只 ...

  5. ym——Android之ListView性能优化

    转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持! Android之ListView性能优化 假设有看过我写过的15k面试题的朋友们一定知 ...

  6. 转:Android应用开发性能优化完全分析

    转自:http://blog.csdn.net/yanbober/article/details/48394201 1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜 ...

  7. 利用 gperftools 对nginx mysql 内存管理 性能优化

    利用 gperftools 对nginx 与 mysql  进行 内存管理  性能优化 降低负载. Gperftools 是由谷歌开发.官方对gperftools 的介绍为: These tools ...

  8. <只看这个就够了。。。>Android自动化测试及性能优化

    Android自动化测试及性能优化 分类: Android Java Tools2012-12-09 23:31 4300人阅读 评论(0) 收藏 举报 软件自动化测试对于程序员来说能够确保软件开发的 ...

  9. Android异常与性能优化相关面试问题-内存管理面试问题详解

    内存管理机制概述: 分配机制:操作系统会为每一个进程分配一个合理的内存大小,从而保证每一个进程能够正常的运行,不至于内存不够使用,或者某个进程占用过多的内存. 回收机制:在系统内存不足的时候,系统有一 ...

随机推荐

  1. [Angular] Reactive Store and AngularFire Observables

    A simple store implemenet: import { Observable } from 'rxjs/Observable'; import { BehaviorSubject } ...

  2. C#复习题

    1.以下(D )不是 C#中方法的參数的类型. A.值类型B.引用型C.输出型D.属性 2.C#中的数据类型分为值类型和引用类型,以下(B )不属于引用类型. A.类 B.枚举 C.接口 D.数组 3 ...

  3. js用button激活 Alert 元素关闭按钮的交互功能

    js用button激活 Alert 元素关闭按钮的交互功能 一.总结 1.点(.)对应class,井号(#)对应id  2.jquery:amaze里面用的jquery,jquery熟悉之后,这些东西 ...

  4. zoj 2724 Windows Message Queue 优先队列

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1724 题目大意: 给出两种操作,GET要求取出当前队首的元素,而PUT会输入名 ...

  5. Activex调试以及m_hWnd为空 解决办法

    1. 点击[开始]->[运行] 命令:regedit.2. 定位到HKEY_LOCALMACHINE -> SOFTWARE -> Microsoft -> Internet ...

  6. Linux上制作Window启动盘

    Linux上制作Window启动盘 注意: U盘在Linux中的标签(依具体情况而定:执行df查看) U盘 ----- /dev/sdb4 格式化U盘 建立U盘的启动分区 安装关键工具 ms-sys ...

  7. 具体解释https是怎样确保安全的

    Https 介绍 什么是Https HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer).是以安全为目标的HTTP通道,简单讲是 ...

  8. [ES7] Handle Errors in Asynchronous Functions

    This lesson shows how regular control flow statements such as try/catch blocks can be used to proper ...

  9. 【codeforces 742C】Arpa's loud Owf and Mehrdad's evil plan

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  10. [Win 8/WP 8]简单实现弹出页更换头像的功能

    在Win 8应用里,对弹出页(Popup)的灵活操作必不可少,下面我们就来简单实现一个. 一.先让Popup弹出到指定位置 先来看看效果图,如图[1]: 下面是前端代码,代码段[1]: <Gri ...