【问题标题】:Recycling Bitmap does not free memory回收位图不会释放内存
【发布时间】:2013-12-23 03:22:20
【问题描述】:

我在TabHost 中有一个Activity,还有其他3 个活动。因此,它们始终处于活动状态(或处于“暂停”状态)。

第一个活动有四个不同的图像(每个约 250kb),它们正在检索大量内存(大约 80MB。只是指出,我加载了屏幕所需的最小尺寸,并且我使用 layout_weight if这有帮助),所以我想尽量减少所需的内存量。

我已经尝试删除OnPause 状态下的图像并再次将它们设置为OnResume,但我没有运气,这是我尝试做的一个示例:

 imageView.Drawable.Callback = null;
 ((BitmapDrawable)imageView.Drawable).Bitmap.Recycle();
 imageView.Drawable.Dispose();
 imageView.SetImageDrawable(null);
 imageView.SetImageBitmap(null);
 GC.Collect();

我不知道删除OnPause 上的Bitmap 是否是最佳策略,但它应该有效。我不明白为什么 GC 不收集ImageView(因为没有外部引用)

编辑 这就是我加载图像的方式。即使我将图像放在 xml 文件中,它也不起作用。此外,我不在乎这段代码,我只想dispose位图。

       void SetBackgroundImages(int imageId, int resId, float width, float height) {
        var imageView = FindViewById<ImageView>(imageId);
        using (var bitmap = DecodeSampledBitmapFromResource(Resources, resId, width, height))
            imageView.SetImageBitmap(bitmap);

    }
    public static Bitmap DecodeSampledBitmapFromResource(Resources res, int resId, float reqWidth, float reqHeight) {

    var options = new BitmapFactory.Options {InJustDecodeBounds = true};
    using (var b = BitmapFactory.DecodeResource(res,resId,options)){}
        options.InSampleSize = CalculateInSampleSize(options, reqWidth, reqHeight);
        options.InJustDecodeBounds = false;
        return BitmapFactory.DecodeResource(res, resId, options);
    }

【问题讨论】:

  • 您究竟是如何加载图像的?简单地告诉ImageView 拉伸或缩放图像,并不意味着您正在以可能的最小尺寸加载它。 Afaik,您还需要 Invalidate ImageView 以释放对 Bitmap 的引用。
  • 感谢您的回复。这不是重点,但我将图像加载为 Xamarin(和 Google)文档点(docs.xamarin.com/recipes/android/resources/general/…),获取样本。我试图使 ImageView 无效(谢谢),但没有区别,在 OnResume 中我得到了 OutOfMemory 异常......
  • 您使用的是其中的哪些部分?请提供您实际将图像加载到视图中的代码。
  • 我编辑了这个问题。我不明白你为什么对我的问题投反对票,我认为这很清楚......无论如何,感谢您尝试帮助我:)
  • 您遗漏了很多重要信息,即使在询问之后也是如此。您是否尝试在将位图分配给 imageview 后立即回收它?

标签: android memory-leaks bitmap xamarin.android xamarin


【解决方案1】:

在删除图像后最后调用java.lang.System.gc() 就可以了。

【讨论】:

  • 其实是java.lang.System.gc();
【解决方案2】:
using (var imageView = FindViewById<ImageView>(Resource.Id.imageView1))
    using (var bitmap    = Android.Graphics.BitmapFactory.DecodeResource(
            this.Resources, Resource.Drawable.Icon))
        imageView.SetImageBitmap(bitmap);

我在几个地方看到了这种方法,另一个是对 ImageView 的 WeakReference 的使用。这些方法可以帮助 GC 正确收集对 ImageView 的引用

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-20
    • 2014-11-17
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 2019-05-15
    • 2010-11-25
    相关资源
    最近更新 更多