如何避免Android应用出现内存溢出OutOfMemoery

作者&投稿:前皇 (若有异议请与网页底部的电邮联系)
如何在Android应用当中避免内存溢出问题~

主要要遵循以下几点:
不要为Context长期保存引用(要引用Context就要使得引用对象和它本身的生命周期保持一致)。
如果要使用到Context,尽量使用ApplicationContext去代替Context,因为ApplicationContext的生命周期较长,引用情况下不会造成内存泄露问题
在你不控制对象的生命周期的情况下避免在你的Activity中使用static变量。尽量使用WeakReference去代替一个static。
垃圾回收器并不保证能准确回收内存,这样在使用自己需要的内容时,主要生命周期和及时释放掉不需要的对象。尽量在Activity的生命周期结束时,在onDestroy中把我们做引用的其他对象做释放,比如:cursor.close()。

  Android的内存主要表现在:
  1. 在Android平台上,长期保持一些资源的引用,造成一些内存不能释放,带来的内存泄露问题很多。比如:Context(下文中提到的Activity都是Context),在一些你需要保持你的首个类对象状态,并且把状态传入其他类对象中时,这样消除掉首个类对象之前,你必须先把接收类对象释放掉。需要注意一点的是:因为在Java或者Android内存机制中,顶点的结点释放前必须保证其他对象没有调用才能被系统GC回收释放。我们来看一段代码:
  @Override
  protected void onCreate(Bundlestate) {
  super.onCreate(state);
  TextViewlabel = new TextView(this);
  label.setText("Leaksare bad");
  setContentView(label);
  }
  这个代码的意思就是我们把一个TextView的实例加载到了我们正在运行的Activity(Context)当中,因此,通过GC回收机制,我们知道,要释放Context,就必须先释放掉引用他的一些对象。如果没有,那在要释放Context的时候,你会发现会有大量的内存溢出。所以在你不小心的情况下内存溢出是一件非常容易的事情。保存一些对象时,同时也会造成内存泄露。最简单的比如说位图(Bitmap),比如说:在屏幕旋转时,会破坏当前保持的一个Activity状态,并且重新申请生成新的Activity,直到新的Activity状态被保存。我们再看一段代码:
  privatestatic DrawablesBackground;
  @Override
  protected void onCreate(Bundlestate) {
  super.onCreate(state);
  TextView label = newTextView(this);
  label.setText("Leaks arebad");
  if (sBackground == null){
  sBackground =getDrawable(R.drawable.large_bitmap);
  }
  label.setBackgroundDrawable(sBackground);
  setContentView(label);
  }
  这个代码是非常快的同时也是错误的。它的内存泄露很容易出在屏幕转移的方向上。虽然我们会发现没有显示的保存Context这个实例,但是当我们把绘制的图连接到一个视图的时候,Drawable就会将被View设置为回调,这就说明,在上述的代码中,其实在绘制TextView到活动中的时候,我们已经引用到了这个Activity。链接情况可以表现为:Drawable->TextView->Context。
  所以在想要释放Context的时候,其实还是保存在内存中,并没有得到释放。
  如何避免这种情况:主要在于。线程最容易出错。大家不要小看线程,在Android里面线程最容易造成内存泄露。线程产生内存泄露的主要原因在于线程生命周期的不可控。下面有一段代码:
  publicclass MyTest extendsActivity {
  @Override
  publicvoid onCreate(BundlesavedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  new MyThread().start();
  }
  privateclass MyThread extends Thread{
  @Override
  public void run() {
  super.run();
  //do somthing
  }
  }
  }
  代码很简单,但是在Android上又来新问题了,当我们在切换视图屏幕的时候(横竖屏),就会重新建立横屏或者竖屏的Activity。我们形象的认为之前建立的Activity会被回收,但是事实如何呢?Java机制不会给你同样的感受,在我们释放Activity之前,因为run函数没有结束,这样MyThread并没有销毁,因此引用它的Activity(Mytest)也有没有被销毁,因此也带来的内存泄露问题。
  有些人喜欢用Android提供的AsyncTask,但事实上AsyncTask的问题更加严重,Thread只有在run函数不结束时才出现这种内存泄露问题,然而AsyncTask内部的实现机制是运用了ThreadPoolExcutor,该类产生的Thread对象的生命周期是不确定的,是应用程序无法控制的,因此如果AsyncTask作为Activity的内部类,就更容易出现内存泄露的问题。
  线程问题的改进方式主要有:
  l 将线程的内部类,改为静态内部类。
  l 在程序中尽量采用弱引用保存Context。
  2. 万恶的bitmap。。。
  Bitmap是一个很万恶的对象,对于一个内存对象,如果该对象所占内存过大,在超出了系统的内存限制时候,内存泄露问题就很明显了。。
  解决bitmap主要是要解决在内存尽量不保存它或者使得采样率变小。在很多场合下,因为我们的图片像素很高,而对于手机屏幕尺寸来说我们并不用那么高像素比例的图片来加载时,我们就可以先把图片的采样率降低在做原来的UI操作。
  如果在我们不需要保存bitmap对象的引用时候,我们还可以用软引用来做替换。具体的实例代码google上面也有很多。
  综上所述,要避免内存泄露,主要要遵循以下几点:
  第一:不要为Context长期保存引用(要引用Context就要使得引用对象和它本身的生命周期保持一致)。
  第二:如果要使用到Context,尽量使用ApplicationContext去代替Context,因为ApplicationContext的生命周期较长,引用情况下不会造成内存泄露问题
  第三:在你不控制对象的生命周期的情况下避免在你的Activity中使用static变量。尽量使用WeakReference去代替一个static。
  第四:垃圾回收器并不保证能准确回收内存,这样在使用自己需要的内容时,主要生命周期和及时释放掉不需要的对象。尽量在Activity的生命周期结束时,在onDestroy中把我们做引用的其他对象做释放,比如:cursor.close()。
  其实我们可以在很多方面使用更少的代码去完成程序。比如:我们可以多的使用9patch图片等。有很多细节地方都可以值得我们去发现、挖掘更多的内存问题。我们要是能做到C/C++对于程序的“谁创建,谁释放”原则,那我们对于内存的把握,并不比Java或Android本身的GC机制差,而且更好的控制内存,能使我们的手机运行得更流畅。

  转载

一、内存溢出 现在的智能手机内存已经足够大,但是对于一个应用程序来说智能手机当中稀缺的内存,仍然是应用程序的一大限制。在Android应用程序开发当中,最常见的内存溢出问题(OOM)是在加载图片时出现的,尤其是在不知道图片大小的情况下。 潜在的内存溢出操作主要包括以下几点: 1、从网络当中加载用户特定的图片。因为直到我们在下载图片的时候我们才知道图片的大小。 2、向Gallery加载图片。因为现在智能手机的摄像头有很高的分辨率,在加载图片的时候需要最图片进行处理,然后才能正常的使用。 请注意一点,Android系统是从系统全局的观念来分配内存以加载图片的,这就意味着,即使你的应用有足够大的内存可用,内存溢出问题(out of memroy,OOM)仍然可能出现,因为所有的应用共享一个加载图片的内存池(我们使用BitmapFactory进行解析)。 二、解决内存溢出问题 原文(Downsampling为了好理解,解释为,程序A)。程序A通过调整像素,同时使其均衡化来降低图片的分辨率。因为不管问题图片是因为太大而不能再手机上正常显现,这个图片都会缩短其宽度以在ImageView当中显示,当图片在ImageView当中显示时,我们会因为加载一些没有必要的原始图片而浪费掉内存。 因此,更加有效的加载图片的时机是在其初始化处理的时候。 以下是处理代码: 1: private static Bitmap getResizedImage(String path, byte[] data, int targetWidth){2:3: BitmapFactory.Options options = new BitmapFactory.Options(); 14: options.inSampleSize = ssize;15:16: Bitmap bm = null;17: try{18: bm = decode(path, data, options); 19: }catch(OutOfMemoryError e){ 39: result = result * 2;40:41: }42:43: return result;44: }三、AQuery当在Android应用程序开发当中使用AQuery组件时,处理这个问题会变的更加的简单。


手机导航的时候老是提醒GPS信号弱,定位不了,求解决办法?
如果不是系统的毛病,可以看看提醒GPS信号弱时附近有没有遮挡物,车内导航的时候有没有干扰物。很多手机的后盖接触不严,也会导致GPS信号弱。可以手动将后盖打开,查看GPS天线,看看有没有洁纯到手机金属部位,如果有,用小镊子给剥离就好了。另外可以使用一款名为AndroiTS-GPS-Test-Pro-1.46-Pro的...

海南麻将的问题
志向是天才的幼苗,经过热爱劳动的双手培育,在肥田沃土里将成长为粗壮的大树。不热爱劳动,不进行 自我教育,志向这棵幼苗也会连根枯死。确定个人志向,选好专业,这是幸福的源泉 erytrhjghkrdtydhfhyghjkghjlkhjioluhi;luho;guuyg;ugg 你好,正版在卫幸--->bbk1533 shiheiosgengandroixitongbukaji有很...

华为p30pro导航是北斗模块,还是软件
华为mate30pro支持北斗导航。确认手机实际是否可以搜到北斗导航卫星,可以在应用市场搜索名为androiTS GPS Test的测试软件,安装到手机后看搜星结果。如果看到卫星ID是200以上的就是北斗导航在运行。北斗导航系统由导航软件自动调用,无法手动指定使用北斗导航系统。此外华为mate30pro还支持L1+L5双频GPS,华为...

中国北斗卫星信号何时可用?
你现在有可能已经在用了。目前市场上的品牌手机都支付GPS、GLONASS、和BDS。平时导航使用的定位,就是上述三个全球定位系统综合定位的结果。如果想亲眼看一下自己手机上的BDS信号,可以安装AndroiTS GPS TEST,编号200以上的,就是BDS的信号。下图就是红米4手机当前接收到的所有卫星信号,其中最下端几个是...

怎样知道手机是用的GPS定位还是北斗定位
中国70%的智能手机都用到了北斗系统,之所以用户感受不到,主要因为手机上经常用GPS三个字母代替了所有导航系统。通过软件或App来检测,这里以安卓手机小米8透明探索版为例。用户可以在应用商店或网络搜索卫星软件《AndroiTS GPS Test》或者小区信号及WiFi网络信道查询《Cellular-Z》,通过App方式查看是否连接...

买什么样的手机性价比最高
三星的 i5800 简约1250元 androil2.1系统 摩托罗拉 xt701 2000元左右 androil2.1系统。 三星的i5700 有白色的,androil2.2 系统的,1450元。

为什么下载个北斗导航还要收费20元?
北斗的导航服务是不收取任何费用的,同样GPS也是不收取任何费用的,用户使用北斗导航时是不用交钱的。但是北斗的通讯服务是需要交钱的。短信收费的情况是个别网友办理了其他类的服务,这些服务并非仅仅是利用了北斗导航系统,其中也存在其他的人工服务费,以及其他运营商提供的额外的服务费用,国家仅仅是承诺不...

哔哩哔哩的移动定向免流量包怎么用啊。。。我用的ios app,看了一天发现...
1、在激活前,请将哔哩哔哩卡插入手机内,确保关闭WIFI,在联通2G\/3G\/4G网络下进行操作。如果您是使用双卡手机操作激活,请将通话主卡、上网主卡均设置为哔哩哔哩卡;2、进入Bilibil手机客户端,iPhone手机点击右下角菜单栏【我的】\/Androi手机点击坐上角的头像,进入【个人中心】,再点击【免流量服务...

QQ游戏积分陕西麻将积分场怎么进?
打开你的qq 下面有qq游戏点击进去添加陕西麻将 然后就可以直接进去了。里面有积分场 新手场 点击可以直接进入 房间你随便进。

哪些手机性价比高,求推荐
我推荐性价比高的手机有华为的荣耀 8X还有小米的红米Note 7。首先说说荣耀 8X这部手机。荣耀8X是华为在2019年上市的一款手机,目前的销售量估计已经突破千万了,销量高不是没有理由的,因为这部手机的性价比是非常高的。首先从外观来看,这部手机的屏占比是非常高的,达到了91%,要知道这部手机是属于...

新疆维吾尔自治区19256604474: 如何避免Android应用出现内存溢出OutOfMemoery -
微平甲状: 1)在循环内尽量不要使用局部变量2)不用的对象即时释放,即指向NULL3)数据库的cursor即时关闭.4)构造adapter时使用缓存contentview5)使用广播调用registerReceiver()后在对应的生命周期方法中调用unregisterReceiver()6)即时关闭InputStream/OutputStream.7)android系统给图片分配的内存只有8M, 图片尽量使用软引用, 较大图片可通过BitmapFactory缩放后再使用,并及时recycle 8)尽量避免static成员变量引用资源耗费过多的实例.

新疆维吾尔自治区19256604474: Android中如何防止内存溢出(摘) -
微平甲状: 但是Android采用的是Java语言编写,所以在很大程度上,Android的内存机制等同于Java的内存机制,在刚开始开发的时候,内存的限制问题会给我们带来内存溢出等严重问题.在我们不使用...

新疆维吾尔自治区19256604474: android怎么防止内存溢出 -
微平甲状: 主要要遵循以下几点: 1. 不要为Context长期保存引用(要引用Context就要使得引用对象和它本身的生命周期保持一致). 2. 如果要使用到Context,尽量使用ApplicationContext去代替Context,因为ApplicationContext的生命周期较长,引用情...

新疆维吾尔自治区19256604474: 怎么解决android内存溢出问题的 -
微平甲状: 一、内存溢出 现在的智能手机内存已经足够大,但是对于一个应用程序来说智能手机当中稀缺的内存,仍然是应用程序的一大限制.在Android应用程序开发当中,最常见的内存溢出问题(OOM)是在加载图片时出现的,尤其是在不知道图片大...

新疆维吾尔自治区19256604474: 如何避免Android内存泄漏 -
微平甲状: 在 Java中,JavaVM拥有自动管理内存的功能,Java的GC能够进行垃圾回收,但是Android中如果ImageView使用过多的Bitmap的话,经常会报OOM(内存溢出).造成内存溢出及解决方案:1. 使用BitmapFactory.decodeStream替代...

新疆维吾尔自治区19256604474: 如何解决Android内存溢出 -
微平甲状: 模拟器RAM比较小,只有8M内存,当我放入的大量的图片(每个100多K左右),就出现上面的原因.由于每张图片先前是压缩的情况.放入到Bitmap的时候,大小会变大,导致超出RAM内存,具体解决办法如下:1,解决加载图片内存溢出的...

新疆维吾尔自治区19256604474: Android 内存溢出怎么解决 -
微平甲状: Android虽然会自动管理内存,JAVA也有garbage collection (GC )内存回收机制.但是如果程序在一次操作中打开几个M的文件,那么通常会出现下面的错误信息.02-04 21:46:08.703: ERROR/dalvikvm-heap(2429): 1920000-byte external ...

新疆维吾尔自治区19256604474: 安卓软件容易常驻内存,如何解决?
微平甲状: 尽量表下载一下无关紧要的软件,内存问题可以用网秦手机卫士优化手机系统解决

新疆维吾尔自治区19256604474: 如何禁止安卓后台缓存 -
微平甲状: 不建议清理..这是安卓系统的设计 这种设计本来就是一个非常好的设计,下次启动程序时,会更快,因为不需要读取界面资源. Android系统这样的设计不仅非常适合移动终端的需要,而且减少了系统崩溃的可能,确保了系统的稳定性. 有...

新疆维吾尔自治区19256604474: 怎样有效的降低安卓运存占用率在百分之50以下? -
微平甲状: 一般来说,占用系统内存的组件主要包括当前运行的进程、自启动进程和硬件应用,下面我们就介绍如何针对这三大类的组件进行有针对性的优化(以平板为例):1.当前正在运行的进程(包括系统后台进程)优化 默认情况下后台启动的服务都...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网