使用Glide加载图片时遭遇OutOf Memory Error问题求助
我之前也碰到过一模一样的问题,折腾了好久才找到根源,给你几个亲测有效的方案,按优先级试试:
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

