Adapter引发内存泄漏排查求助:聚焦RecyclerView相关方法
解决嵌套RecyclerView导致的内存泄漏问题
你提到已经排除了WeakReference和Listeners的问题,并且锁定泄漏点在OnCreateViewHolder或OnBindViewHolder里,结合你在OutterAdapter的OnBindViewHolder中每次都调用setAdapter(innerAdapter)创建新InnerAdapter的操作,这大概率就是内存泄漏的根源,我来给你拆解问题并提供解决方案:
问题根源分析
每次外层RecyclerView绑定Item时都创建新的InnerAdapter,会带来两个关键问题:
- 旧的InnerAdapter实例会被残留的引用(比如内层RecyclerView的缓存、ViewHolder的引用)持有,无法被GC回收,随着列表滚动次数增加,会积累大量无用的Adapter实例占用内存。
- 如果InnerAdapter持有了上下文(比如Activity)、外层数据源或者外层ViewHolder的强引用,这些对象也会被连带无法回收,形成泄漏链。
具体解决方案
1. 复用InnerAdapter,避免重复创建
不要在OnBindViewHolder里每次都new InnerAdapter,而是做缓存复用:
- 可以在OutterAdapter的构造方法中预先初始化好所有InnerAdapter(如果外层数据源固定);
- 或者用
Map<Integer, InnerAdapter>来缓存位置对应的InnerAdapter,首次创建后后续绑定直接复用,只更新数据源:
// OutterAdapter类内的缓存容器 private final Map<Integer, InnerAdapter> innerAdapterCache = new HashMap<>(); @Override public void onBindViewHolder(@NonNull OutterViewHolder holder, int position) { // 获取当前外层Item对应的内层数据源 List<InnerItemModel> innerData = outerDataList.get(position).getInnerItems(); // 从缓存获取或创建InnerAdapter InnerAdapter innerAdapter = innerAdapterCache.get(position); if (innerAdapter == null) { innerAdapter = new InnerAdapter(innerData); innerAdapterCache.put(position, innerAdapter); } else { // 仅更新数据源,不创建新Adapter innerAdapter.refreshData(innerData); } holder.innerRecyclerView.setAdapter(innerAdapter); }
2. 在ViewHolder回收时切断引用链
外层RecyclerView的ViewHolder被回收时,要清空内层RecyclerView的Adapter,避免残留引用:
@Override public void onViewRecycled(@NonNull OutterViewHolder holder) { super.onViewRecycled(holder); // 清空内层Adapter,切断引用 holder.innerRecyclerView.setAdapter(null); // 如果需要,也可以清空内层RecyclerView的布局管理器或数据 holder.innerRecyclerView.setLayoutManager(null); }
3. 优化InnerAdapter的引用持有
- 若InnerAdapter需要上下文,使用
getApplicationContext()而非Activity的上下文,避免持有Activity的强引用; - 检查InnerAdapter内的Listeners、回调是否用WeakReference包裹(即使你之前处理了外层的Listener,内层的也不能忽略);
- 确保InnerAdapter内没有持有外层ViewHolder或OutterAdapter的强引用,必要时用WeakReference替代。
4. 用LeakCanary精准定位泄漏路径
虽然你已经锁定了大致范围,但用LeakCanary可以帮你明确看到到底是哪个对象被谁持有,比如是不是InnerAdapter持有了Activity,还是外层缓存的Adapter过多导致内存占用,这能帮你快速验证解决方案是否有效。
内容的提问来源于stack exchange,提问作者MaaAn13
相关产品推荐
相关产品推荐

