You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Glide加载图片时遭遇OutOf Memory Error问题求助

解决RecyclerView加载图片时的OutOfMemoryError问题

我之前也碰到过一模一样的问题,折腾了好久才找到根源,给你几个亲测有效的方案,按优先级试试:

1. 强制Glide加载与ImageView匹配尺寸的图片

这是最容易被忽略的核心点!如果你的ImageView是固定尺寸(比如200x200dp),但Glide默认加载原图尺寸的Bitmap,会导致内存浪费严重,重复加载后直接触发OOM。

解决方法:用override()方法指定和ImageView一致的尺寸,或者动态获取ImageView的实际宽高:

// 方式1:直接写死ImageView的固定尺寸(推荐,避免获取宽高的耗时)
Glide.with(this)
     .load(imageUrl)
     .override(400, 400) // 对应200dp x 200dp(根据设备密度调整)
     .into(imageView);

// 方式2:动态获取ImageView的宽高(适合wrap_content的情况)
imageView.post(() -> {
    int width = imageView.getWidth();
    int height = imageView.getHeight();
    Glide.with(this)
         .load(imageUrl)
         .override(width, height)
         .into(imageView);
});

2. 在Fragment销毁时主动清理Glide请求

如果重复访问同一个Fragment,之前的Glide请求可能还在后台运行,加载完成后Fragment已经销毁,Bitmap无法被及时回收,导致内存堆积。

在Fragment的onDestroyView()方法中,主动清理对应ImageView的Glide请求:

@Override
public void onDestroyView() {
    super.onDestroyView();
    // 清理当前Fragment所有ImageView的Glide请求
    Glide.with(this).clear(imageView);
}

另外,确保你用的是Glide.with(fragment)而非Glide.with(activity),这样Glide会自动跟随Fragment的生命周期管理请求,销毁时自动取消未完成的任务。

3. 避免ViewHolder内存泄漏

检查你的RecyclerView Adapter的ViewHolder是否持有了Fragment/Activity的强引用,比如在ViewHolder里存储了Context对象。正确的做法是用itemView.getContext()获取上下文,或者用WeakReference包裹:

public class MyViewHolder extends RecyclerView.ViewHolder {
    private ImageView imageView;

    public MyViewHolder(@NonNull View itemView) {
        super(itemView);
        imageView = itemView.findViewById(R.id.image_view);
        // 不要在这里存储Context!要用的时候直接拿itemView.getContext()
    }

    public void bind(String url) {
        Glide.with(itemView.getContext())
             .load(url)
             .into(imageView);
    }
}

同时,给Adapter设置setHasStableIds(true)并实现getItemId(),让RecyclerView尽可能复用ViewHolder,减少对象创建:

@Override
public void onCreate() {
    super.onCreate();
    adapter.setHasStableIds(true);
}

@Override
public long getItemId(int position) {
    // 返回每个item的唯一ID,比如数据模型的id
    return dataList.get(position).getId();
}

4. 优化Glide的内存缓存策略

你之前用的skipMemoryCache(true)其实会适得其反——关闭内存缓存后,Glide每次都要重新从网络下载并解码图片,反而会增加内存开销和CPU负载。正确的做法是合理配置内存缓存大小:

创建自定义的AppGlideModule(需要添加Glide的注解依赖),调整内存缓存为应用可用内存的合理比例:

@GlideModule
public class CustomGlideModule extends AppGlideModule {
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        MemorySizeCalculator calculator = new MemorySizeCalculator.Builder(context).build();
        // 比如设置为默认缓存大小的50%,根据你的应用需求调整
        int customCacheSize = (int) (calculator.getMemoryCacheSize() * 0.5);
        builder.setMemoryCache(new LruResourceCache(customCacheSize));
    }
}

5. 降低图片解码的内存占用

默认的ARGB_8888格式每个像素占4字节,换成RGB_565格式可以减少一半内存(每个像素2字节),如果你的图片不需要透明通道,强烈建议开启:

Glide.with(this)
     .load(imageUrl)
     .format(DecodeFormat.PREFER_RGB_565)
     .into(imageView);

另外,尽量让后端提供WebP格式的图片,WebP比JPG/PNG体积小25%-50%,Glide默认支持WebP解码,能显著降低内存占用。

6. 排查内存泄漏

用Android Studio的Memory Profiler抓取Heap Dump,查看是否有大量Bitmap对象或Fragment实例没有被回收。也可以用LeakCanary工具自动检测内存泄漏,它会帮你定位到泄漏的引用链(比如是否有静态变量持有Fragment的引用)。


内容的提问来源于stack exchange,提问作者Sourav Nag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:35:52