Android OutOfMemoryError :?

Estoy obteniendo esporádicamente un OutOfMemoryError: (Heap Size=49187KB, Allocated=41957KB) en una de mis aplicaciones. ¿Qué puedo hacer para diagnosticar esto?

  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 

Esta es la línea donde está sucediendo:

 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(); } } 

tal vez esto te ayude?

agregar manifiesto

android> v3

  

Soluciones comunes:

1. Corrige tus contextos:

Intente usar el contexto apropiado: por ejemplo, dado que se puede ver un Toast en muchas actividades en lugar de en una sola, use getApplicationContext() para tostadas y, como los servicios pueden seguir ejecutándose aunque una actividad haya terminado, inicie un servicio con:

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

Use esta tabla como una guía rápida para saber qué contexto es el apropiado: enter image description here

Artículo original sobre el contexto aquí .

2. Verifique que en realidad esté terminando sus servicios.

Por ejemplo, tengo un intentService que usa la API del servicio de ubicación de Google. Y olvidé llamar a googleApiClient.disconnect(); :

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

3. Compruebe el uso de imágenes y mapas de bits:

Si estás usando la librería de Square Picasso , encontré que estaba perdiendo memoria al no usar .fit() , que redujo drásticamente la huella de mi memoria de 50MB en promedio a menos de 19MB:

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

4. Si está utilizando receptores de difusión anule el registro.

5. Si está usando java.util.Observer (patrón de observador):

Asegúrese de utilizar deleteObserver(observer);

Puede hacer lo siguiente para evitar esto.

 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(); } } 

La carga de Bitmap en Imageview siempre ha sido una de las causas de la falta de memoria, por lo que es muy común, por lo que debemos manejar imágenes y mapas de bits con mucho cuidado. Lo que puede hacer es configurar cualquier bitmap de fondo en su vista de la imagen, primero obtener el dibujable y reciclarlo para que se elimine de la memoria y luego establecer el nuevo bitmap. Esto ayudará a evitar cualquier problema OOM. Promover. Puede utilizar BitmapFactoryOptions para reducir el tamaño de su bitmap. me gusta:

 // 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; } 

Antes de cargar imágenes en la memoria, comprima sus imágenes usando

 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()); 

Si está obteniendo su bitmap de un recurso, en cuyo caso la dimensión del bitmap dependerá de la densidad de la pantalla del teléfono

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

Esto podría ocurrir por varias razones, es posible que mantenga las referencias a otras partes de su código demasiado tiempo. Es posible que esté cargando mapas de bits grandes que, junto con aferrarse a muchas referencias, le den OOM, etc.

Normalmente, cuando se produce un OOM, se crea un hprof (instantánea del Heap) en la raíz de la tarjeta SD (o almacenamiento interno si la tarjeta SD no existe), que se puede leer con herramientas como Eclipse MAT (incluida en las herramientas de Android si usa Eclipse). Primero, podría necesitar convertir el hprof con la herramienta hprof-conv . Aquí hay un tutorial sobre cómo usar Eclipse MAT: Investigar su uso de RAM . El informe de sospechosos de fugas es una buena primera lectura cuando se carga hprof en Eclipse MAT

Después de crear un perfil, puede leer sobre cómo cargar imágenes de forma eficaz desde la visualización de mapas de bits de manera eficiente.

También hay varias bibliotecas de carga de imágenes populares, como cargador de imágenes universal y picasso disponibles, que hacen lo que necesita con facilidad.

Bitmap smile final = BitmapFactory.decodeResource (getResources (), R.drawable.emo_im_happy);

Llamada

String pathname=BitMapToString(smile);

y luego llamar

 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; } 

por favor ponga todas las funciones en su actividad y llame solo a setImageNew() y pase el parámetro en imageview, sdcardpathname y activity

Espero que no se bloquee después de implementar este código. porque me surge el mismo problema que tú ..

Esto puede suceder si el recurso de bitmap no está dispuesto correctamente. Es mejor leer las dimensiones para ver si se ajusta a la memoria. http://developer.android.com/training/displaying-bitmaps/load-bitmap.html