Android OutOfMemoryError:?

我在我的一个应用程序中使用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 { reultMatchHeaderContainer.setBackgroundResource(R.drawable.matches_placeholder_result2x); } catch (OutOfMemoryError e) { e.printStackTrace(); } } 

Solutions Collecting From Web of "Android OutOfMemoryError:?"

也许这对你有帮助?

添加清单

android> v3

 <application .... android:largeHeap="true"> 

常见的修复:

1.修复你的上下文:

尝试使用合适的上下文:例如,由于Toast可以在许多活动中看到,而不是在一个活动中看到,因此可以使用getApplicationContext()作为Toa​​st,因为即使活动已经结束,服务也可以继续运行。

Intent myService = new Intent(getApplicationContext(), MyService.class)

使用此表作为适用于上下文的快速指南: 在这里输入图像说明

这里的上下文的原始文章 。

2.检查你是否正在完成你的服务。

例如,我有一个使用谷歌位置服务API的intentService。 我忘了打电话给googleApiClient.disconnect();

 //Disconnect from API onDestroy() if (googleApiClient.isConnected()) { LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, GoogleLocationService.this); googleApiClient.disconnect(); } 

3.检查图像和位图的使用情况:

如果你正在使用Square的图书馆毕加索,我发现我没有使用.fit()内存泄漏,这大大减less了我的内存占用从平均50MB到less于19MB:

 Picasso.with(ActivityExample.this) //Activity context .load(object.getImageUrl()) .fit() //This avoided the OutOfMemoryError .centerCrop() //makes image to not stretch .into(imageView); 

4.如果您正在使用广播接收器取消注册。

5.如果使用java.util.Observer (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; } 

将图像加载到内存之前使用压缩图像

 Bitmap original = BitmapFactory.decodeStream(getAssets().open("1024x768.jpg")); ByteArrayOutputStream out = new ByteArrayOutputStream(); original.compress(Bitmap.CompressFormat.PNG, 100, out); Bitmap decoded = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray())); Log.e("Original dimensions", original.getWidth()+" "+original.getHeight()); Log.e("Compressed dimensions", decoded.getWidth()+" "+decoded.getHeight()); 

如果您正在从资源创build位图,则位图维度将取决于手机屏幕密度

 Bitmap bitmap=((BitmapDrawable)getResources().getDrawable(R.drawable.img_1024x768)).getBitmap(); Log.e("Dimensions", bitmap.getWidth()+" "+bitmap.getHeight()); 

发生这种情况的原因有很多,您可能会将代码的其他部分保留太长时间。 你可能正在加载到大的位图,一起拿着许多引用给你OOM,等等。

通常当OOM发生时,在SD卡的根目录(或者SD卡的内部存储不存在)上创build一个hprof (堆的快照),可以通过Eclipse MAT等工具读取(如果使用的话,包含在android工具中)蚀)。 首先可能需要用hprof-conv工具转换hprof。 以下是一个如何使用Eclipse MAT的教程: 调查你的RAM使用情况 。 当hprof在Eclipse MAT中加载时,泄漏可疑报告是首先读取的

分析完成后,您可以阅读如何有效地显示位图来有效加载图像

还有一些stream行的图像加载库,例如通用图像加载器和可用的毕加索,可以轻松地完成您所需要的function。

最终位图微笑= BitmapFactory.decodeResource(getResources(),R.drawable.emo_im_happy);

呼叫

String pathname=BitMapToString(smile);

然后打电话

 setImagesNew(linearview,pathname,activity); 

 public String BitMapToString(Bitmap bitmap) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); byte[] b = baos.toByteArray(); String temp = Base64.encodeToString(b, Base64.DEFAULT); return temp; } public static void setImagesNew(LinearLayout linearLayout, String pathName, Activity activity) { Bitmap bmp = decodeSampledBitmapFromResource(pathName, getDeviceWidth(activity), getDeviceHeight(activity)); linearLayout.setBackgroundDrawable(bmp); bmp = null; System.gc(); Runtime.getRuntime().gc(); } public static Bitmap decodeSampledBitmapFromResource(String pathName, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(pathName, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(pathName, options); } public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfHeight = height / 2; final int halfWidth = width / 2; // Calculate the largest inSampleSize value that is a power of 2 and // keeps both // height and width larger than the requested height and width. while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) { inSampleSize *= 2; } } return inSampleSize; } @SuppressLint("NewApi") public static int getDeviceWidth(Activity activity) { int deviceWidth = 0; Point size = new Point(); WindowManager windowManager = activity.getWindowManager(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { windowManager.getDefaultDisplay().getSize(size); deviceWidth = size.x; } else { Display display = windowManager.getDefaultDisplay(); deviceWidth = display.getWidth(); } return deviceWidth; } @SuppressLint("NewApi") public static int getDeviceHeight(Activity activity) { int deviceHeight = 0; Point size = new Point(); WindowManager windowManager = activity.getWindowManager(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { windowManager.getDefaultDisplay().getSize(size); deviceHeight = size.y; } else { Display display = windowManager.getDefaultDisplay(); deviceHeight = display.getHeight(); } return deviceHeight; } 

请把所有的函数放在你的activity中,只调用setImageNew() ,在imageview,sdcardpathname和activity中传递参数

我希望在你实现这个代码之后它不会崩溃。 因为我遇到同样的问题

如果位图资源configuration不正确,可能会发生这种情况。 阅读尺寸以查看它是否适合内存更好。 http://developer.android.com/training/displaying-bitmaps/load-bitmap.html