【问题标题】:Android memory leak with images from assets来自资产的图像的Android内存泄漏
【发布时间】:2012-09-22 15:33:02
【问题描述】:

我从资产中获取图像并分配给 imageView,一切正常,但是当我看到堆内存大小时,当我一次又一次加载同一页面时,它会继续增长,下面是我用来从中获取图像的代码资产文件夹。

private Bitmap getBitmapFromAsset(String strName) throws IOException
{
    AssetManager assetManager = getAssets();

    InputStream istr = assetManager.open(strName);
    Bitmap bitmap = BitmapFactory.decodeStream(istr);

    return bitmap;
}

    //Code to assign bitmap to imageview
    ImageView itemImage = (ImageView) findViewById(R.id.itemImage);
    try {
        Bitmap bm = getBitmapFromAsset("full/" + Uri.parse(menuItem.getFullImage()).getLastPathSegment());
        itemImage.setImageBitmap(bm);
    } catch (IOException e) {
        e.printStackTrace();
    }

这就是我正在做的所有事情,有没有我需要回收位图的地方?

【问题讨论】:

标签: java android memory-leaks


【解决方案1】:

在你的 onDestroy 添加

   @Override
        public void onDestroy()
        {

            super.onDestroy();
            if(bm != null)
            {
                bm.recycle();

            }
}

另外取内存转储并分析转储使用MAT。如果您需要帮助,请参阅此视频tutorial

【讨论】:

  • 谢谢。即使,您的回答对我不起作用。但它间接解决了我的问题......我使用了 AssetFileDescriptor 对象并且没有关闭......所以它也被泄露了......我发现 AssetFileDescriptor 对象可以通过 close() 方法关闭。无论如何。我解决了我的问题。无论如何,谢谢。
【解决方案2】:

检查一下

使用完位图后,使用以下语句 bm = null; 并编写 System.gc();在 ondestroy() 中(如果需要,在 onPause() 中),看看是否有效

【讨论】:

  • 调用 GC 不是解决内存问题的正确方法。
  • @Matsemann 哦,那么对不起答案。使用 bm = null;解决问题?
  • 没问题,但是你是怎么用的?
  • public void onPause() { super.onPause(); if (bm != null) { Log.i("recycle?", "yes"); bm.recycle(); } }
  • 你用过Bitmap吗 bm = getBitmapFromAsset("full/" + Uri.parse(menuItem.getFullImage()).getLastPathSegment());原样?还是您将其更改为 bm = getBitmapFromAsset("full/" + Uri.parse(menuItem.getFullImage()).getLastPathSegment());
【解决方案3】:

Bitmap 对象一旦使用完毕,需要调用recycle() 方法来释放原生资源。

Bitmap#recycle()

释放与此位图关联的本机对象,并清除对像素数据的引用。这不会同步释放像素数据;如果没有其他引用,它只是允许它被垃圾收集。该位图被标记为“死”,这意味着如果调用 getPixels() 或 setPixels() 将引发异常,并且不会绘制任何内容。此操作无法反转,因此只有在您确定位图没有进一步用途时才应调用它。这是一个高级调用,通常不需要调用,因为当没有更多对该位图的引用时,正常的 GC 进程将释放该内存。

【讨论】:

    【解决方案4】:

    实际上我正在使用一个由所有活动扩展的父活动,并且该活动已向 LocationListener 注册,因此 LocationListener 正在防止该活动被破坏。

    【讨论】:

      【解决方案5】:

      除了已经说过的内容之外,我还会关闭资产流,因为根据您在资产上运行的平台,可能不会自动关闭资产。 即使它是你保留文件描述符的时间超过你需要的时间。这是一种有限的资源,因此可能会导致其他东西走向南方。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-13
        相关资源
        最近更新 更多