内存泄漏案例分享4-异步任务流内存泄漏
案例4——异步任务内存泄漏
异步任务,代指起子线程异步完成一些数据操作、网络接口请求等,通常会使用以下API:
- Runnbale,Thread,线程池
- RxJava
- HandlerThread
而这些异步任务很有可能操作内存泄漏,下面我们以Rxjava为例,演示此问题,线程、线程池的问题也类似,就不再一一演示了。
大多数项目的网络基础库,传入Rxjava的是匿名Observer,任务过多时,未执行的任务的Observer会持有当前页面的引用,造成内存泄漏,接下来我们将演示这个场景
先提出几个问题:
- rxjava就会存在内存泄漏吗?
- subscribe传入的匿名内部类Consumer实例不会造成内存泄漏吗?
- 异步任务返回时,Activity已经处于onDestroyed状态,Observer持有`Activity引用,Activity内存还能被回收吗?
我们来验证一下rxjava的泄漏场景:
假设我们在Activity#onResume方法里,写了异步任务,任务结束后,设置view的属性,在任务结束之前,我们会调用Activity#finsh操作退出当前页面,如下坨屎:页面在12秒后实际已经处于`onDestroyed状态了
为了演示问题,我将延时时间增大,写成12秒,模拟异步任务返回的情况
Observable.timer(12000, TimeUnit.MILLISECONDS).subscribeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Long>() {@Overridepublic void accept(Long aLong) throws Exception {dataBinding.layoutWelcome.setVisibility(View.GONE);...其他view 的引用}});
测试步骤为:
- 进入Activity
- 立刻退出Activity
- 一段时间之后观察Activity的内存是否被回收
我们得到一份hprof文件,来分析下

老规矩先看下Instance-Details-Instance区域,Activity的生命周期onDestroyed的值是否为true,按步骤点击一看,确实为true,证明Activity已经离开窗口了,处于销毁的生命周期中,我们期望的时候垃圾回收器可以回收Activity占据的内存,但事实上我们在Hprof文件看到了,表明Activity占据的内存未回收。
紧着着我们面临下一个问题,如何找到导致Activity内存泄漏的原因呢?谁引用了Activity?
点击Instance-Details-References区域,我们可以很快得到答案,按步骤点击Jump to Source

果然,立刻跳转到内存泄漏所在的代码块,终于我们通过分析hprof文件找到了问题所在:

那么如何解决此问题呢?
rxjava提供了CompositeDisposable解决此类泄漏问题,做法如下:
创建实例对象
/*** 管理rxjava的任务,及时释放,不执行emitter#onNext*/public CompositeDisposable compositeDisposable = new CompositeDisposable();
用compositeDisposable实例去控制任务的生命周期
compositeDisposable.add(Observable.timer(12000, TimeUnit.MILLISECONDS).subscribeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Long>() {@Overridepublic void accept(Long aLong) throws Exception {dataBinding.layoutWelcome.setVisibility(View.GONE);processIntent(getIntent());}}));
页面生命周期onDestroyed期间清空任务
@Overrideprotected void onDestroy() {super.onDestroy();compositeDisposable.clear();}
总结
优化后的效果:

优化后可看到Depth为空,GC root 为空,表明没有其他实例引用Activity了,当垃圾回收器扫描到此实例,该实例内存会被回收。
还记得开头的问题吗?
- rxjava就会存在内存泄漏吗?答:会存在,consumer作为Activity的内部类,持有当前Activity的引用,任务未结束,Activity已销毁就会出现内存泄漏
- subscribe传入的匿名内部类Consumer实例不会造成内存泄漏吗?答:只要是匿名内部类,就很有可能内存泄漏,上例子已经证明会产生内存问题。
- 异步任务返回时,Activity已经处于onDestroyed状态,Observer持有`Activity引用,Activity内存还能被回收吗?答:无法被回收
相关文章:
内存泄漏案例分享4-异步任务流内存泄漏
案例4——异步任务内存泄漏 异步任务,代指起子线程异步完成一些数据操作、网络接口请求等,通常会使用以下API: Runnbale,Thread,线程池RxJavaHandlerThread 而这些异步任务很有可能操作内存泄漏,下面我们以Rxjava为…...
【机器学习300问】100、怎么理解卷积神经网络CNN中的池化操作?
一、什么是池化? 卷积神经网络(CNN)中的池化(Pooling)操作是一种下采样技术,其目的是减少数据的空间维度(宽度和高度),同时保持最重要的特征并降低计算复杂度。池化操作不…...
RPA机器人流程自动化如何优化人力资源工作流程
人力资源部门在支持员工和改善整体工作环节方面扮演着至关重要的角色,但是在人资管理的日常工作中,充斥着大量基于规则的重复性任务,例如简历筛选、面试安排、员工数据管理、培训管理、绩效管理等,这些任务通常需要工作人员花费大…...
OpenHarmony开发者大会2024:鸿心聚力 智引未来
2024年5月25日,OpenAtom OpenHarmony(简称“OpenHarmony")委员会以“鸿心聚力,智引未来”为主题,在创新之城深圳举办OpenHarmony开发者大会2024,为开发者、产业组织、生态伙伴和行业客户搭建一个交流、分享和学习…...
新楚文化知网收录文学艺术类期刊投稿
《新楚文化》是由国家新闻出版总署批准,湖北省文学艺术界联合会主管,湖北今古传奇传媒集团有限公司主办的正规期刊。主要刊登文化、文学、艺术类稿件;包括传统文化、非遗、历史文化、地方文化、中外友好文化交流、文学作品研究、艺术研究等方…...
基于vue3速学angular
因为工作原因,需要接手新的项目,新的项目是angular框架的,自学下和vue3的区别,写篇博客记录下: 参考:https://zhuanlan.zhihu.com/p/546843290?utm_id0 1.结构上: vue3:一个vue文件ÿ…...
链游中的代币(Token)或加密货币(Cryptocurrency)是如何产生和使用的?
在区块链游戏(链游)中,代币和加密货币不仅是游戏经济的核心,也是连接现实世界与虚拟游戏世界的桥梁。这些数字货币不仅赋予了游戏内资产的真实价值,还为玩家提供了全新的互动和交易方式。下面,我们将深入探…...
2024年5月23日 (周四) 叶子游戏新闻
《Unclogged》Steam页面上线 马桶主题恐怖逃脱解谜Brody制作并发行,一款奇葩创意马桶主题恐怖逃脱解谜新游《Unclogged》Steam页面上线,本作暂不支持中文。 Meta人工智能主管杨立昆 大语言模型不会达到人类智能水平IT之家今日(5月23日&#x…...
猫毛过敏终结者!宠物空气净化器让你告别红眼和喷嚏
猫毛过敏是一种常见的过敏性疾病,影响着全球数百万人的日常生活。这种过敏反应通常是由于对猫皮屑、唾液或尿液中的蛋白质产生免疫反应而引起的。症状可能包括打喷嚏、流鼻涕、眼睛痒、皮肤疹和呼吸困难,严重影响患者的舒适度和生活质量。对于猫毛过敏者…...
xgboost项目实战-保险赔偿额预测与信用卡评分预测001
目录 算法代码 原理 算法流程 xgb.train中的参数介绍 params min_child_weight gamma 技巧 算法代码 代码获取方式:链接:https://pan.baidu.com/s/1QV7nMC5ds5wSh-M9kuiwew?pwdx48l 提取码:x48l 特征直方图统计: fig, …...
子网划分,交换机原理与配置
子网划分 IP地址 IPv4由32位二进制数组成,一般用点分十进制来表示 IPv4是由32位二进制数组成,分成四组,第组八位。例如:11000000.10101000.00000000.00000010 为了便于配置通常表示成点分十进制形式例如:192.168.0.2 255.255.255.0 IPv6由128位组成&…...
记mapboxGL实现鼠标经过高亮时的一个问题
概述 mapboxGL实现鼠标经过高亮可通过注册图层的mousemove和moveout事件来实现,在mousemove事件中可以拿到当前经过的要素,但是当使用该要素时,发现在某个地图级别下会有线和面数据展示不全的情况。究其原因,发现是mapboxGL在绘图…...
AI重塑了我的工作流
阅读内容 Inhai: Agentic Workflow:AI 重塑了我的工作流 4 种主要的 Agentic Workflow 设计模式 Reflection(反思):让 Agent 审视和修正自己生成的输出。 举例:如果有两个 Agent:一个负责 Coding&#…...
vue使用Less报错semi-colon expectedcss(css-semicolonexpected)的解决方法
1、将 styleint 依赖项添加到项目中 npm install --save-dev stylelint stylelint-config-standard2、在根目录中添加stylelint.config.js文件(与package.json同级) module.exports {extends: ["stylelint-config-standard"],rules: {"…...
如何使用golang自带工具对代码进行覆盖率测试
在 Go 语言中,测试代码覆盖率通常使用 go test 命令结合 -cover 和 -coverprofile 1. 基本代码覆盖率报告 在项目目录下运行以下命令 go test -cover这将在控制台输出一个代码覆盖率的百分比。但是,这种方式不会保存覆盖率数据(可以指定目…...
Android studio版本和Android gradle plugin版本对应表
1.Android studio 版本的升级,一个方面上看主要是升级对AGP最高版本的支持 2.那为什么AGP要出高版本呢,主要支持高版本的API,真是一环扣一环...
JavaRedis-主从集群-分片-数据结构-回收处理-缓存问题
一、主从集群 1.主从集群 主从集群读写分离,主能读能写,从只能读,读的数据是同步主的 docker搭建: docker-compose 这里设置网络模式为model,就直接暴露在了宿主机中,就不用映射端口了 不改就是默认的桥…...
Java原生JDBC概览
Java原生JDBC概览 一、是什么? JDBC是Java DataBase Connectivity的缩写,它是Java程序访问数据库的标准接口。 Java代码并不是直接通过TCP连接去访问数据库,而是通过JDBC接口来访问,而JDBC接口则通过JDBC驱动来实现对数据库的访…...
C# 跨线程访问UI组件,serialPort1串口接收数据
在Windows应用程序(例如WinForms或WPF)中,UI组件(如按钮、文本框等)都在主线程(也称为UI线程)上运行。当你在一个非UI线程(例如,一个后台线程或者网络请求线程࿰…...
D - New Friends(AtCoder Beginner Contest 350)
题目链接: D - New Friends (atcoder.jp) 题目大意: 题目解析: 题目的大致意思: 假如A和B是朋友 B和C也是朋友 那么当A和C不是朋友的时候 可以通过B让A和C也成为朋友 问你增加了多少对的朋友关系 题目分析: 咱们可以从图论去考虑 当这一群是一个连通块 那么这一群点(人) 都…...
Phi-4-mini-reasoning真实作品:微分方程求解+物理意义解释双模态输出
Phi-4-mini-reasoning真实作品:微分方程求解物理意义解释双模态输出 1. 模型简介 Phi-4-mini-reasoning是一个基于合成数据构建的轻量级开源模型,专注于高质量、密集推理的数据处理能力。作为Phi-4模型家族的一员,它经过专门微调以提升数学…...
优化Blazor渲染逻辑的实践
在Blazor应用程序开发中,页面渲染逻辑的优化是提升用户体验的重要环节。特别是当页面包含多个条件渲染的组件时,如何高效地控制渲染流程成为了一个关键问题。本文将通过一个实际的案例,展示如何在Blazor中使用RenderFragment和return语句来优化页面渲染逻辑。 背景 假设我…...
千问3.5-2B参数详解:max_new_tokens=192如何平衡响应长度与推理延迟?实测数据
千问3.5-2B参数详解:max_new_tokens192如何平衡响应长度与推理延迟?实测数据 1. 模型概述 千问3.5-2B是Qwen系列中的小型视觉语言模型,具备图片理解与文本生成双重能力。这个2B参数的轻量级模型特别适合需要快速响应的应用场景,…...
OpenClaw命令行增强:gemma-3-12b-it解释复杂指令并自动补全
OpenClaw命令行增强:gemma-3-12b-it解释复杂指令并自动补全 1. 为什么需要命令行增强工具 作为一个常年与终端打交道的开发者,我经常遇到这样的困境:记得某个命令的功能,却想不起具体参数;或者面对复杂的管道操作时&…...
千问3.5-2B辅助MATLAB科学计算:算法实现与结果可视化脚本生成
千问3.5-2B辅助MATLAB科学计算:算法实现与结果可视化脚本生成 1. 科研计算的新助手 作为一名经常使用MATLAB的科研工作者,你是否遇到过这样的困扰:明明知道要解决什么数学问题,却卡在代码实现环节?或者花了大量时间调…...
OpenClaw模型微调:Kimi-VL-A3B-Thinking领域适配数据准备指南
OpenClaw模型微调:Kimi-VL-A3B-Thinking领域适配数据准备指南 1. 为什么需要领域特定数据微调 当我第一次尝试将Kimi-VL-A3B-Thinking模型应用到医疗影像分析场景时,发现模型对专业术语的理解和图像特征的把握都不够精准。这让我意识到,即使…...
10点滑动平均滤波器:嵌入式零依赖高效实现
1. 项目概述MovingAverageFilter 是一个轻量级、零依赖的嵌入式数字滤波器实现,专为资源受限的微控制器环境设计。其核心功能是执行固定长度(10点)的滑动平均(Moving Average)运算,并在每次新采样输入后立即…...
escodegen浏览器端使用教程:在Web环境中实现代码生成
escodegen浏览器端使用教程:在Web环境中实现代码生成 【免费下载链接】escodegen ECMAScript code generator 项目地址: https://gitcode.com/gh_mirrors/es/escodegen escodegen是一个强大的ECMAScript代码生成器,它能够将抽象语法树(AST)转换回…...
避开Arduino PID编程的3个常见坑:为什么你的控制总是不稳?
Arduino PID控制实战:避开3个致命陷阱实现精准调节 当你在深夜盯着反复震荡的电机转速曲线,或是加热棒温度始终无法稳定的数据时,是否怀疑过自己复制的PID代码有问题?这不是你的错觉——大多数Arduino PID控制问题都源于三个容易被…...
OpenClaw多通道管理:千问3.5-9B同时服务飞书与钉钉
OpenClaw多通道管理:千问3.5-9B同时服务飞书与钉钉 1. 为什么需要多通道管理? 上周三凌晨两点,我被手机连续震动吵醒——团队同时用飞书和钉钉给我发了紧急需求。半梦半醒间突然想到:既然OpenClaw能自动化处理消息,为…...
