2017-03-20 45 views
0

我面对这个错误:如何检查内存泄漏?以及如何解决这些问题?

FATAL EXCEPTION: main Process: com.petyaar, PID: 18056 java.lang.OutOfMemoryError: Failed to allocate a 63701004 byte allocation with 16777024 free bytes and 40MB until OOM at dalvik.system.VMRuntime.newNonMovableArray(Native Method) at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:639) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:615) at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:391) at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:419) at com.petyaar.OwnerBio.OwnerBioUpdate.onCaptureImageResult(OwnerBioUpdate.java:611) at com.petyaar.OwnerBio.OwnerBioUpdate.onActivityResult(OwnerBioUpdate.java:643) at android.app.Activity.dispatchActivityResult(Activity.java:6508) at android.app.ActivityThread.deliverResults(ActivityThread.java:3702) at android.app.ActivityThread.handleSendResult(ActivityThread.java:3749) at android.app.ActivityThread.access$1400(ActivityThread.java:153) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1400) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5441) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)

我不知道如何解决这个问题,我也一直在监测的“Android监视器”我的内存分配。内存分配不断增加,即使我没有与应用程序交互。它高达500MB +

这就是我通过摄像头拍摄的图像。

private void onCaptureImageResult(Intent data) { 

    Bitmap thumbnail = null; 


    String[] projection = {MediaStore.Images.Media.DATA}; 
    Cursor cursor = managedQuery(mCapturedImageURI, projection, null, 
      null, null); 
    int column_index_data = cursor 
      .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
    cursor.moveToFirst(); 

    //THIS IS WHAT YOU WANT! 
    String capturedImageFilePath = cursor.getString(column_index_data); 

    filename = capturedImageFilePath.substring(capturedImageFilePath.lastIndexOf("/") + 1); 
    thumbnail = BitmapFactory.decodeFile(capturedImageFilePath); 

    ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 
    thumbnail.compress(Bitmap.CompressFormat.JPEG, 50, bytes); 

    thumbnail=Bitmap.createScaledBitmap(thumbnail, 200, 300, true); 

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
     Log.i("final camera size", String.valueOf(thumbnail.getAllocationByteCount())); 
    } 
    File destination = new File(Environment.getExternalStorageDirectory(), 
      System.currentTimeMillis() + ".jpg"); 
    byte[] byteArray = bytes.toByteArray(); 
    encoded = Base64.encodeToString(byteArray, Base64.DEFAULT); 
    Log.e("base64string name", encoded); 

    Log.e("Image name", capturedImageFilePath); 
    FileOutputStream fo; 
    try { 
     destination.createNewFile(); 
     fo = new FileOutputStream(destination); 
     fo.write(bytes.toByteArray()); 
     fo.close(); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    profile_image.setImageBitmap(thumbnail); 
} 

请告诉我如何解决此问题。

+0

在应用程序标签的AndroidManifest.xml文件中放上这个标签android:largeHeap =“true” –

+0

为什么这样? 尽管我已经阅读过,但在android:largeHeap =“true”中也存在其他问题。 和不断增加内存大小的原因是什么? – rajat44

+0

大堆的原因[检查此链接](http://stackoverflow.com/questions/27396892/what-are-advantages-of-setting-largeheap-to-true) –

回答

2

Leakcanary是你内存泄漏的好朋友。它非常易于使用,可以帮助您在应用程序中查找内存泄漏。在你的情况下,它似乎不是内存泄漏,而只是一些不断分配内存的循环。无论如何,试试Leakcanary。如果它没有帮助,请尝试使用堆转储来查找应用的哪个部分正在使用所有内存。关于它的更多信息可以参见here

就你而言,它似乎与你在Bitmap上做的一些工作有关。确保你从内存中释放它们。 另外,请记住,图像是以Android为基础的内存大小(以像素为单位),而不是基于MB的大小。所以真正简单的png是10000x10000,但只有1MB会占用比1000x1000 jpeg多3MB的内存。

+0

我已经创建了.hprof文件,但我不知道如何使用它来获取内存泄漏。你能指导我一样吗? – rajat44

+0

堆转储基本上是您的应用程序分配的所有内存。在那里你可以看到哪些对象正在占用大部分内存,并且基于那些发现有bug的应用程序的一部分。如果它不是一个大的应用程序,你可以粘贴代码的一部分,你正在做一些繁重的工作(图像处理,处理大文本文件等) –

+0

我已经安装了LeakCanary,但是当我的应用程序崩溃时它没有显示任何通知由于outOfMemory异常。 当我知道错误的行号时,应该遵循哪些步骤。对于前 - 我的一个日志中,我在setContentView(布局)中出现错误。 我能从这个错误中得到什么? – rajat44