Android 内存泄漏优化汇总

android内存泄漏优化摘要 博客分类: android

android内存溢出OutOfMemoryError .

android移动应用程序的内存分配一般是8凯瑟琳约,不正确地假定处理内存处理非常easy创建OutOfMemoryError。我们的产品是最常见的错误是OutOfMemoryError的异常,

在解决这个异常时在网上发现非常多关于OutOfMemoryError的原因的介绍。

OutOfMemoryError主要由下面几种情况造成:

1.数据库的cursor没有关闭。

操作Sqlite数据库时,Cursor是数据库表中每一行的集合,Cursor提供了非常多方法,能够非常方便的读取数据库中的值,

能够依据索引。列名等获取数据库中的值,通过游标的方式能够调用moveToNext()移到下一行

当我们操作完数据库后。一定要记得调用Cursor对象的close()来关闭游标,释放资源。

2.构造adapter没有使用缓存contentview。

在继承BaseAdapter时会让我们重写getView(int position, View   convertView, ViewGroup parent)方法。

第二个參数convertView就是我们要用到的重用的对象

Java代码

[email protected]

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

3.    ViewHolder vHolder = null;

4.               //假设convertView对象为空则创建新对象,不为空则复用

5.    if (convertView == null) {

6.        convertView = inflater.inflate(..., null);

7.        // 创建 ViewHodler 对象

8.        vHolder = new ViewHolder();

9.        vHolder.img= (ImageView) convertView.findViewById(...);

10.        vHolder.tv= (TextView) convertView

11.                .findViewById(...);

12.        // 将ViewHodler保存到Tag中

13.        convertView.setTag(vHolder);

14.    } else {

15.                       //当convertView不为空时,通过getTag()得到View

16.        vHolder = (ViewHolder) convertView.getTag();

17.    }

18.    // 给对象赋值。改动显示的值

19.    vHolder.img.setImageBitmap(...);

20.    vHolder.tv.setText(...);

21.    return convertView;

22.}

23.       //将显示的View 包装成类

24.static class ViewHolder {

25.    TextView tv;

26.    ImageView img;

27.}

@Override

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

ViewHolder vHolder = null;

//假设convertView对象为空则创建新对象,不为空则复用

if (convertView == null) {

convertView = inflater.inflate(..., null);

// 创建 ViewHodler 对象

vHolder = new ViewHolder();

vHolder.img= (ImageView) convertView.findViewById(...);

vHolder.tv= (TextView) convertView

.findViewById(...);

// 将ViewHodler保存到Tag中

convertView.setTag(vHolder);

} else {

//当convertView不为空时,通过getTag()得到View

vHolder = (ViewHolder) convertView.getTag();

}

// 给对象赋值,改动显示的值

vHolder.img.setImageBitmap(...);

vHolder.tv.setText(...);

return convertView;

}

//将显示的View 包装成类

static class ViewHolder {

TextView tv;

ImageView img;

}

这里仅仅讲用法,详细性能測试文章请见:

ListView中getView的原理+怎样在ListView中放置多个item

http://www.cnblogs.com/xiaowenji/archive/2010/12/08/1900579.html

Android开发之ListView适配器(Adapter)优化

http://shinfocom.iteye.com/blog/1231511

3.调用registerReceiver()后未调用unregisterReceiver().

广播接收者(BroadcastReceiver)常常在应用中用到。能够在多线程任务完毕后发送广播通知UI更新,也能够接收系统广播实现一些功能

能够通过代码的方式注冊:

IntentFilter postFilter = new IntentFilter();

postFilter.addAction(getPackageName() + ".background.job");

this.registerReceiver(receiver, postFilter);

当我们Activity中使用了registerReceiver()方法注冊了BroadcastReceiver。一定要在Activity的生命周期内调用unregisterReceiver()方法取消注冊

也就是说registerReceiver()和unregisterReceiver()方法一定要成对出现,通常我们能够重写Activity的onDestory()方法:

Java代码

[email protected]

2.protected void onDestroy() {

3.      this.unregisterReceiver(receiver);

4.      super.onDestroy();

5.}

@Override

protected void onDestroy() {

this.unregisterReceiver(receiver);

super.onDestroy();

}

4.未关闭InputStream/OutputStream。

这个就不多说了,我们操作完输入输出流都要关闭流

5.Bitmap使用后未调用recycle()。

图片处理不好是造成内存溢出的又一个头号原因,(在我们的产品中也有体现),

当我们处理完图片之后能够通过调用recycle()方法来回收图片对象

Java代码

1.if(!bitmap.isRecycled())

2.{

3.    bitmap.recycle()

4.}

if(!bitmap.isRecycled())

{

bitmap.recycle()

}

除此之外:

直接使用ImageView显示bitmap会占用较多资源。特别是图片较大的时候,可能导致崩溃。

使用BitmapFactory.Options设置inSampleSize, 这样做能够降低对系统资源的要求。

属性值inSampleSize表示缩略图大小为原始图片大小的几分之中的一个,即假设这个值为2,则取出的缩略图的宽和高都是原始图片的1/2,图片大小就为原始大小的1/4。

BitmapFactory.Options bitmapFactoryOptions = new BitmapFactory.Options();

bitmapFactoryOptions.inJustDecodeBounds = true;

bitmapFactoryOptions.inSampleSize = 2;

// 这里一定要将其设置回false,由于之前我们将其设置成了true

// 设置inJustDecodeBounds为true后,decodeFile并不分配空间,即。BitmapFactory解码出来的Bitmap为Null,但可计算出原始图片的长度和宽度

options.inJustDecodeBounds = false;

Bitmap bmp = BitmapFactory.decodeFile(sourceBitmap, options);

6.Context泄漏。

这是一个非常隐晦的OutOfMemoryError的情况。先看一个Android官网提供的样例:

Java代码

1.private static Drawable sBackground;

[email protected]

3.protected void onCreate(Bundle state) {

4.  super.onCreate(state);

5.

6.  TextView label = new TextView(this);

7.  label.setText("Leaks are bad");

8.

9.  if (sBackground == null) {

10.    sBackground = getDrawable(R.drawable.large_bitmap);

11.  }

12.  label.setBackgroundDrawable(sBackground);

13.

14.  setContentView(label);

15.}

private static Drawable sBackground;

@Override

protected void onCreate(Bundle state) {

super.onCreate(state);

TextView label = new TextView(this);

label.setText("Leaks are bad");

if (sBackground == null) {

sBackground = getDrawable(R.drawable.large_bitmap);

}

label.setBackgroundDrawable(sBackground);

setContentView(label);

}

这段代码效率非常快,但同一时候又是极其错误的。

在第一次屏幕方向切换时它泄露了一開始创建的Activity。当一个Drawable附加到一个 View上时,

View会将其作为一个callback设定到Drawable上。

上述的代码片段。意味着Drawable拥有一个TextView的引用,

而TextView又拥有Activity(Context类型)的引用。换句话说,Drawable拥有了很多其它的对象引用。即使Activity被 销毁,内存仍然不会被释放。

另外,对Context的引用超过它本身的生命周期,也会导致Context泄漏。所以尽量使用Application这样的Context类型。

这样的Context拥有和应用程序一样长的生命周期,而且不依赖Activity的生命周期。

假设你打算保存一个长时间的对象,

而且其须要一个 Context,记得使用Application对象。你能够通过调用Context.getApplicationContext()或 Activity.getApplication()轻松得到Application对象。

近期遇到一种情况引起了Context泄漏,就是在Activity销毁时,里面有其它线程没有停。

总结一下避免Context泄漏应该注意的问题:

1.使用Application这样的Context类型。

2.注意对Context的引用不要超过它本身的生命周期。

3.谨慎的使用“static”keyword。

4.Context里假设有线程。一定要在onDestroy()里及时停掉。

7.statickeyword

当类成员变量声明为static后,它属于类而不是属于对象。假设我们将非常大的资源对象(Bitmap。context等待)声明static。那么这些资源不会被回收的回收目标。

它会一直存在。因此,使用statickeyword成员变量定义时要小心。

时间: 2024-12-19 06:09:20

Android 内存泄漏优化汇总的相关文章

Android 内存泄漏优化总结

1,验证是否为汉字 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 // 验证昵称     private boolean verifyNickname() {         String nickname = edt_username.getText().toString();         if (nickname == null || ni

Android内存性能优化(内部资料总结)

刚入门的童鞋肯能都会有一个疑问,Java不是有虚拟机了么,内存会自动化管理,我们就不必要手动的释放资源了,反正系统会给我们完成.其实Java中没有指针的概念,但是指针的使用方式依然存在,一味的依赖系统的gc,很容易就造成了内存的浪费.   Java基于垃圾回收的内存机制 Java的内存管理机制会自动回收无用对象所占用的内存,减轻手工管理内存的负担 1.C/C++: 从申请.使用.释放都需要手工管理 2.Java:无用的对象的内存会被自动回收 什么样的对象是无用的对象 1.Java通过引用来操作一

Android内存泄漏

韩梦飞沙  韩亚飞  [email protected]  yue31313  han_meng_fei_sha #Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题.内存泄漏大家都不陌生了,简单粗俗的讲,就是该被释放的对象没有释放,一直被某个或某些实例所持有却不再被使用导致 GC 不能回收.最近自己阅读了大量相关的文档资料,打算做个 总结 沉淀下来跟大家一起分享和学习,也给自己一个警示,以后 coding 时怎么避免这些情况,提高应用的体验

Android内存性能优化(内部资料总结) eoe转载

刚入门的童鞋肯能都会有一个疑问,Java不是有虚拟机了么,内存会自动化管理,我们就不必要手动的释放资源了,反正系统会给我们完成.其实Java中没有指针的概念,但是指针的使用方式依然存在,一味的依赖系统的gc,很容易就造成了内存的浪费. Java基于垃圾回收的内存机制 Java的内存管理机制会自动回收无用对象所占用的内存,减轻手工管理内存的负担 1.C/C++: 从申请.使用.释放都需要手工管理 2.Java:无用的对象的内存会被自动回收 什么样的对象是无用的对象 1.Java通过引用来操作一个具

新年过后献上关于Android内存泄漏的种种总结

Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问 题.内存泄漏大家都不陌生了,简单粗俗的讲,就是该被释放的对象没有释放,一 直被某个或某些实例所持有却不再被使用导致 GC 不能回收 我会从 java 内存泄漏的基础知识开始,并通过具体例子来说明 Android 引起内存泄 漏的各种原因,以及如何利用工具来分析应用内存泄漏,最后再做总结. 篇幅有些长,大家可以分几节来看! (顺手留下GitHub链接,需要获取相关面试等内容的可以自己去找)htt

android 内存泄漏分析技巧

java虚拟机运行一般都有一个内存界限,超过这个界限,就会报outofmemory.这个时候一般都是存在内存泄漏.解决内存泄漏问题,窃以为分为两个步骤:分析应用程序是否真的有内存泄漏,找到内存泄漏的地方.这两个步骤都不是一般意义上的调试,直接打log,断点调试都不是太给力.动脑筋想一想,内存问题应该在很多地方上都会出现,这么常见的问题应该是有工具的.android现在更可以说是一个生态系统,当然也有很多开发辅助工具.在前面的两个步骤中都有很强大的武器,熟练的掌握这些利器,分析问题就会事半功倍.

android内存泄漏系列- 分析hprof文件

转载请注明出处 http://www.cnblogs.com/weiwangnuanyang/p/5703702.html ,谢谢. 如果只是想确定一下某一个场景是否有内存泄漏,AndroidStadio的控制台就有一个好工具,反复操作观察曲线是否上扬,如果曲线上扬则说明内存泄漏 但是,上面的工具不够强大,不能看出内存中驻留的具体的类和类的引用关系. 下面就来重点介绍一下,解决android内存泄漏必备利器-Memory Analysis; 具体安装方式请移步度娘. 我们这里重点介绍如何利用Me

Android 内存泄漏总结

Java中的内存泄漏 java内存泄漏大家都不陌生了,简单粗俗的讲,就是该被释放的对象没有释放,一直被某个或某些实例所持有却不再被使用导致 GC 不能回收.在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连:其次,这些对象是无用的,即程序以后不会再使用这些对象.如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存. 在C++中,内存泄漏的范围更大一些.有些对象被

Android内存泄漏的各种原因详解

转:http://mobile.51cto.com/abased-406286.htm 1.资源对象没关闭造成的内存泄漏 描述: 资源性对象比如(Cursor,File文件等)往往都用了一些缓冲,我们在不使用的时候,应该及时关闭它们,以便它们的缓冲及时回收内存.它们的缓冲不仅存在于 java虚拟机内,还存在于java虚拟机外.如果我们仅仅是把它的引用设置为null,而不关闭它们,往往会造成内存泄漏.因为有些资源性对象,比如 SQLiteCursor(在析构函数finalize(),如果我们没有关