`
v5qqbrowser
  • 浏览: 355083 次
文章分类
社区版块
存档分类
最新评论

编写android加载图片的程序时,遇到了内存泄露问题!

 
阅读更多

Log如下:

04-04 18:16:32.774: E/dalvikvm-heap(30873): 10036224-byte external allocation too large for this process.
04-04 18:16:32.805: E/GraphicsJNI(30873): VM won't let us allocate 10036224 bytes
04-04 18:16:32.813: D/dalvikvm(30873): GC_FOR_MALLOC freed 0K, 51% free 6259K/12615K, external 22123K/24171K, paused 22ms
04-04 18:16:32.813: D/skia(30873): --- decoder->decode returned false
04-04 18:16:32.813: W/dalvikvm(30873): threadid=15: thread exiting with uncaught exception (group=0x40015568)
04-04 18:16:32.821: E/AndroidRuntime(30873): FATAL EXCEPTION: AsyncTask #3
04-04 18:16:32.821: E/AndroidRuntime(30873): java.lang.RuntimeException: An error occured while executing doInBackground()
04-04 18:16:32.821: E/AndroidRuntime(30873): 	at android.os.AsyncTask$3.done(AsyncTask.java:200)
04-04 18:16:32.821: E/AndroidRuntime(30873): 	at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
04-04 18:16:32.821: E/AndroidRuntime(30873): 	at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
04-04 18:16:32.821: E/AndroidRuntime(30873): 	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
04-04 18:16:32.821: E/AndroidRuntime(30873): 	at java.util.concurrent.FutureTask.run(FutureTask.java:138)
04-04 18:16:32.821: E/AndroidRuntime(30873): 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
04-04 18:16:32.821: E/AndroidRuntime(30873): 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
04-04 18:16:32.821: E/AndroidRuntime(30873): 	at java.lang.Thread.run(Thread.java:1019)
04-04 18:16:32.821: E/AndroidRuntime(30873): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
04-04 18:16:32.821: E/AndroidRuntime(30873): 	at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
04-04 18:16:32.821: E/AndroidRuntime(30873): 	at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:419)
04-04 18:16:32.821: E/AndroidRuntime(30873): 	at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:432)
04-04 18:16:32.821: E/AndroidRuntime(30873): 	at com.jiadebin.ar.arnavigator.ARDetailActivity$wsAsyncTask.doInBackground(ARDetailActivity.java:220)
04-04 18:16:32.821: E/AndroidRuntime(30873): 	at com.jiadebin.ar.arnavigator.ARDetailActivity$wsAsyncTask.doInBackground(ARDetailActivity.java:1)
04-04 18:16:32.821: E/AndroidRuntime(30873): 	at android.os.AsyncTask$2.call(AsyncTask.java:185)
04-04 18:16:32.821: E/AndroidRuntime(30873): 	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
04-04 18:16:32.821: E/AndroidRuntime(30873): 	... 4 more


我的程序是在一个activity里用一个AsyncTask在后台加载Bitmap图片(从网络服务器上加载),这个activity被调用两次之后就不能继续调用了,第三次调用时就出现了这个问题然后程序异常退出,看Log里说貌似是每一次调用加载线程之后,这个线程并没有从内存中销毁,而是继续存在,所以导致后面再次新建该类线程时,内存泄露啦!

在网上找了一下,遇到这类问题的人很多,通常的原因就是我们加载的图片太大,我看了一下我的图片,用500W像素的Defy拍的,原始大小一般都在800KB左右,这样大的图片才导致了内存泄露,网上大神们给的通常的解决方法是,用BitmapFactory解码时加上设置好的options指令(我就是没用options),通常Options如下设定:

BitmapFactory.Options options=new Options();
options.inDither=false; /*不进行图片抖动处理*/
options.inPreferredConfig=null; /*设置让解码器以最佳方式解码*/
options.inSampleSize=4; /*图片长宽方向缩小倍数*/
Bitmapimg=BitmapFactory.decodeByteArray(buffer, 0, buffer.length, options);

这样修改后,我发现传到手机上的图片一般都是200KB左右了,即缩小为原来的1/4,而且看起来还行,没怎么失真,几乎不影响观看效果,问题也解决了~

对了,最好在你使用完Bitmap之后,调用一下recycle()方法,这样更有利于内存回收。



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics