Android中如何避免OOM

血红的双手。 提交于 2019-12-10 08:19:48

       手机内存比较小,随时可能发生溢出的情况,所以避免内存泄露非常重要,否则程序二话不说直接崩溃。。下面的内容总结一下自己的经验以及学习成果。有错误或者有补充的欢迎跟帖讨论。
     1.避免对activity的超过生命周期的引用。(尽量使用application代替activity)。因为程序一般是由很多个Activity构成的,从一个Activity跳转了以后,系统就有可能回收这个Activity的各种内存占用。可是此时如果你的一些不可回收变量(比如静态变量)保持了对此Activity对象的引用,那么GC就不会对此Activity进行回收,无故占用了大量的内存。这种情况最好的办法就是用application代替activity。用Context.getApplicationContext() 或者 Activity.getApplication()可以很方便的得到application对象。具体参考帖子 http://www.eoeandroid.com/forum.php?mod=viewthread&tid=173353  
       2.有些不得不缓存在内存中的图片大字符串等,最好使用软引用或者弱引用。最经典的例子就是异步下载图片,图片会保存到一个HashMap中,下载一张就保存一张到HashMap中。此时hashmap中图片越来越多内存就容易不够用。软引用很好的解决了这个问题。当系统内存不足时,会回收弱引用的内存。我在附件中给出了一个相关的很经典异步下载软引用缓存的demo,大家可以下载看看。注意修改程序中联网的url。
       3.请在调用位图进行图片处理(比如draw)后进行内存回收。bitmap.recycle();这样会把刚刚用过的图片占用的内存释放。这个不用解释了,很简单。
        4.将图片压入内存得到bitmap之前先利用BitmapFactory.Options的inSampleSize的值得到压缩图片,这样会省内存。比如inSampleSize=2,图片将压缩为原图的1/2,占用内存也会变为1/2,而且这样的处理是在加载到内存之前进行的。这在处理很大图片时是必须的。具体的代码如下:

// 得到压缩过的图片
public Bitmap getThumBitmapFromFile(String imageFile)
{
  BitmapFactory.Options opts = new BitmapFactory.Options();
  opts.inJustDecodeBounds = true; // 只计算尺寸,不output
  BitmapFactory.decodeFile(imageFile, opts); // 这步的decodeFile只是为了得到opts的原始尺寸
  // opts.inSampleSize = computeSampleSize(opts, -1, 128 * 128);
  // //计算合适的输出尺寸(第三个参数是最大能接受的像素值)
  opts.inSampleSize = getOptionsSampleSize(opts, 100, 200);
  opts.inJustDecodeBounds = false; // output
  try
  {
   Bitmap bmp = BitmapFactory.decodeFile(imageFile, opts); // 这步decodeFile才是真的output
   return bmp;
  }
  catch (OutOfMemoryError err)
  {
  }
  return null;
}
private int getOptionsSampleSize(BitmapFactory.Options options, int newWidth, int newHeight)
{
  int radioWidth = (int) Math.ceil(options.outWidth / newWidth);
  int radioHeight = (int) Math.ceil(options.outHeight / newHeight);
  if (radioWidth > 1 || radioHeight > 1)
  {
   return radioWidth > radioHeight ? radioWidth : radioHeight;
  }
  else
  {
   return 1;
  }
}

      5.要像C程序员一样去留意new出来的对象的生命周期,尽量不要由于各种复杂的引用导致GC不能及时的甚至永远不能回收某块内存。对象用完后请显式设为null更容易引起GC的注意而且还可以养成注意对象生命周期的习惯,不是new出来就不管了而是要注意销毁。还有就是有必要的时候调用一下System.gc()对GC做一下提醒。

   本文引用自:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=180008&extra=page%3D1&page=1
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!