如何检查内存泄漏?以及如何解决这些问题?

时间:2017-03-20 11:31:53

标签: android memory-leaks

我遇到了这个错误:

  

致命的例外:主要                     过程:com.petyaar,PID:18056                     java.lang.OutOfMemoryError:无法分配带有16777024个空闲字节的63701004字节分配和40MB直到OOM                         at dalvik.system.VMRuntime.newNonMovableArray(Native Method)                         在android.graphics.BitmapFactory.nativeDecodeStream(本机方法)                         在android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:639)                         在android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:615)                         在android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:391)                         在android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:419)                         在com.petyaar.OwnerBio.OwnerBioUpdate.onCaptureImageResult(OwnerBioUpdate.java:611)                         在com.petyaar.OwnerBio.OwnerBioUpdate.onActivityResult(OwnerBioUpdate.java:643)                         在android.app.Activity.dispatchActivityResult(Activity.java:6508)                         在android.app.ActivityThread.deliverResults(ActivityThread.java:3702)                         在android.app.ActivityThread.handleSendResult(ActivityThread.java:3749)                         在android.app.ActivityThread.access $ 1400(ActivityThread.java:153)                         在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1400)                         在android.os.Handler.dispatchMessage(Handler.java:102)                         在android.os.Looper.loop(Looper.java:148)                         在android.app.ActivityThread.main(ActivityThread.java:5441)                         at java.lang.reflect.Method.invoke(Native Method)                         在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:738)                         在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)

我不知道如何解决这个问题,我也一直在“Android Monitor”中监控我的内存分配。即使我没有与应用程序交互,内存分配也在不断增加。它高达 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);
}

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

1 个答案:

答案 0 :(得分:2)

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

在您的情况下,它似乎与您在Bitmaps上进行的某些工作有关。确保从内存中释放它们。 此外,请记住,图像会根据其大小(以像素为单位)在Android中占用内存,而不是基于其大小(以MB为单位)。所以非常简单的png是10000x10000,但只有1MB,比1000x1000 jpeg(3MB)需要更多的内存。