Android中如何避免OOM


       手机内存比较小,随时可能发生溢出的状况,因此避免内存泄露很是重要,不然程序二话不说直接崩溃。。下面的内容总结一下本身的经验以及学习成果。有错误或者有补充的欢迎跟帖讨论。
     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
相关文章
相关标签/搜索