我偶尔会OutOfMemoryError: (Heap Size=49187KB, Allocated=41957KB)
在我的一个应用程序中获得一个.我该怎么做才能诊断出来?
01-09 10:32:02.079: E/dalvikvm(8077): Out of memory: Heap Size=49187KB, Allocated=41957KB, Limit=49152KB 01-09 10:32:02.079: E/dalvikvm(8077): Extra info: Footprint=48611KB, Allowed Footprint=49187KB, Trimmed=7852KB 01-09 10:32:02.079: D/skia(8077): --- decoder->decode returned false 01-09 10:32:02.079: D/AndroidRuntime(8077): Shutting down VM 01-09 10:32:02.079: W/dalvikvm(8077): threadid=1: thread exiting with uncaught exception (group=0x40a97228) 01-09 10:32:02.079: E/AndroidRuntime(8077): FATAL EXCEPTION: main 01-09 10:32:02.079: E/AndroidRuntime(8077): java.lang.OutOfMemoryError: (Heap Size=49187KB, Allocated=41957KB) 01-09 10:32:02.079: E/AndroidRuntime(8077): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 01-09 10:32:02.079: E/AndroidRuntime(8077): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:486) 01-09 10:32:02.079: E/AndroidRuntime(8077): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:773) 01-09 10:32:02.079: E/AndroidRuntime(8077): at android.content.res.Resources.loadDrawable(Resources.java:2044) 01-09 10:32:02.079: E/AndroidRuntime(8077): at android.content.res.Resources.getDrawable(Resources.java:675) 01-09 10:32:02.079: E/AndroidRuntime(8077): at android.view.View.setBackgroundResource(View.java:11776) 01-09 10:32:02.079: E/AndroidRuntime(8077): at com.blsk.bigtoss.ImageLoader.DisplayImage(ImageLoader.java:81) 01-09 10:32:02.079: E/AndroidRuntime(8077): at com.blsk.bigtoss.MatchActivity$MatchAsyncTask.onPostExecute(MatchActivity.java:1768) 01-09 10:32:02.079: E/AndroidRuntime(8077): at android.os.AsyncTask.finish(AsyncTask.java:602) 01-09 10:32:02.079: E/AndroidRuntime(8077): at android.os.AsyncTask.access$600(AsyncTask.java:156) 01-09 10:32:02.079: E/AndroidRuntime(8077): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615) 01-09 10:32:02.079: E/AndroidRuntime(8077): at android.os.Handler.dispatchMessage(Handler.java:99) 01-09 10:32:02.079: E/AndroidRuntime(8077): at android.os.Looper.loop(Looper.java:156) 01-09 10:32:02.079: E/AndroidRuntime(8077): at android.app.ActivityThread.main(ActivityThread.java:4987) 01-09 10:32:02.079: E/AndroidRuntime(8077): at java.lang.reflect.Method.invokeNative(Native Method) 01-09 10:32:02.079: E/AndroidRuntime(8077): at java.lang.reflect.Method.invoke(Method.java:511) 01-09 10:32:02.079: E/AndroidRuntime(8077): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 01-09 10:32:02.079: E/AndroidRuntime(8077): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 01-09 10:32:02.079: E/AndroidRuntime(8077): at dalvik.system.NativeStart.main(Native Method) 01-09 10:32:02.099: E/EmbeddedLogger(1612): App crashed! Process: com.blsk.bigtoss 01-09 10:32:02.099: E/EmbeddedLogger(1612): App crashed! Package: com.blsk.bigtoss v6 (1.2) 01-09 10:32:02.129: E/EmbeddedLogger(1612): Application Label: Cricket
这就是它发生的路线:
LinearLayout resultMatchHeaderContainer = new LinearLayout(activity); if (!resultImagePath.equals("")) { imageLoader.DisplayImage(resultImagePath,resultMatchHeaderContainer, -1,modifiedHeight, R.drawable.matches_placeholder_result2x); } else { try { resultMatchHeaderContainer.setBackgroundResource(R.drawable.matches_placeholder_result2x); } catch (OutOfMemoryError e) { e.printStackTrace(); } }
SKULL.. 42
也许这对你有帮助吗?
添加清单
android> v3
在所有情况下都不建议使用largeHeap,请非常小心地使用它,它可能会减慢其他正在运行的应用程序,并且还会影响应用程序的反应性,因为垃圾收集器会被更频繁地请求.有关更多信息,请查看Google i/o https://www.youtube.com/watch?v=_CruQY55HOk上的此演讲 (13认同)
永远不要因为内存不足而需要快速修复而请求大堆 - 只有当您确切知道所有内存的分配位置以及必须保留的原因时才应使用它.然而,即使你确信你的应用程序可以证明大堆的合理性,你应该避免在任何可能的范围内请求它.请参阅https://developer.android.com/training/articles/memory.html (4认同)
CommonSenseC.. 34
常见修复:
尝试使用适当的上下文:例如,因为Toast可以在许多活动中看到而不是仅在一个活动中使用,getApplicationContext()
用于祝酒,并且即使活动已经结束,服务也可以继续运行,因此启动服务:
Intent myService = new Intent(getApplicationContext(), MyService.class)
使用此表作为适当的上下文的快速指南:
关于上下文的原始文章.
例如,我有一个使用谷歌位置服务API的intentService.我忘了打电话googleApiClient.disconnect();
:
//Disconnect from API onDestroy() if (googleApiClient.isConnected()) { LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, GoogleLocationService.this); googleApiClient.disconnect(); }
如果你正在使用square的库Picasso,我发现我没有使用它来泄漏内存.fit()
,这大大减少了我的内存占用,从平均50MB到小于19MB:
Picasso.with(ActivityExample.this) //Activity context .load(object.getImageUrl()) .fit() //This avoided the OutOfMemoryError .centerCrop() //makes image to not stretch .into(imageView);
java.util.Observer
(观察者模式):一定要使用 deleteObserver(observer);
您可以执行以下操作以避免此问题.
Drawable drawable = resultMatchHeaderContainer.getDrawable(); if (drawable instanceof BitmapDrawable) { BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; if (bitmapDrawable != null) { Bitmap bitmap = bitmapDrawable.getBitmap(); if (bitmap != null && !bitmap.isRecycled()) bitmap.recycle(); } }
在Imageview中加载位图一直是内存不足问题的原因,这是非常常见的,所以我们必须非常小心地处理imageview和位图.您可以做的是在将任何背景位图设置到您的imageview时,首先获取drawable并将其重新循环,以便将其从内存中删除,然后设置新的位图.这有助于避免任何OOM问题.进一步.您可以使用BitmapFactoryOptions来减小位图的大小.喜欢:
// decodes image and scales it to reduce memory consumption private Bitmap decodeFile(File f) { try { // decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; FileInputStream stream1 = new FileInputStream(f); BitmapFactory.decodeStream(stream1, null, o); stream1.close(); // Find the correct scale value. It should be the power of 2. int width_tmp = o.outWidth, height_tmp = o.outHeight; int scale = 1; while (true) { if (width_tmp / 2 < REQUIRED_WIDTH || height_tmp / 2 < REQUIRED_HIGHT) break; width_tmp /= 2; height_tmp /= 2; scale *= 2; } // decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; FileInputStream stream2 = new FileInputStream(f); Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2); stream2.close(); return bitmap; } catch (FileNotFoundException e) { } catch (IOException e) { e.printStackTrace(); } return null; }
尝试使用适当的上下文:例如,因为Toast可以在许多活动中看到而不是仅在一个活动中使用,getApplicationContext()
用于祝酒,并且即使活动已经结束,服务也可以继续运行,因此启动服务:
Intent myService = new Intent(getApplicationContext(), MyService.class)
使用此表作为适当的上下文的快速指南:
关于上下文的原始文章.
例如,我有一个使用谷歌位置服务API的intentService.我忘了打电话googleApiClient.disconnect();
:
//Disconnect from API onDestroy() if (googleApiClient.isConnected()) { LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, GoogleLocationService.this); googleApiClient.disconnect(); }
如果你正在使用square的库Picasso,我发现我没有使用它来泄漏内存.fit()
,这大大减少了我的内存占用,从平均50MB到小于19MB:
Picasso.with(ActivityExample.this) //Activity context .load(object.getImageUrl()) .fit() //This avoided the OutOfMemoryError .centerCrop() //makes image to not stretch .into(imageView);
java.util.Observer
(观察者模式):一定要使用 deleteObserver(observer);
也许这对你有帮助吗?
添加清单
android> v3
<application .... android:largeHeap="true">