内存泄漏案例分享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也成为朋友 问你增加了多少对的朋友关系 题目分析: 咱们可以从图论去考虑 当这一群是一个连通块 那么这一群点(人) 都…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
鸿蒙HarmonyOS 5军旗小游戏实现指南
1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发,采用DevEco Studio实现,包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...
Mysql故障排插与环境优化
前置知识点 最上层是一些客户端和连接服务,包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念,为通过安全认证接入的客户端提供线程。同样在该层上可…...
深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙
WebGL:在浏览器中解锁3D世界的魔法钥匙 引言:网页的边界正在消失 在数字化浪潮的推动下,网页早已不再是静态信息的展示窗口。如今,我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室,甚至沉浸式的V…...
SQL注入篇-sqlmap的配置和使用
在之前的皮卡丘靶场第五期SQL注入的内容中我们谈到了sqlmap,但是由于很多朋友看不了解命令行格式,所以是纯手动获取数据库信息的 接下来我们就用sqlmap来进行皮卡丘靶场的sql注入学习,链接:https://wwhc.lanzoue.com/ifJY32ybh6vc…...
Linux操作系统共享Windows操作系统的文件
目录 一、共享文件 二、挂载 一、共享文件 点击虚拟机选项-设置 点击选项,设置文件夹共享为总是启用,点击添加,可添加需要共享的文件夹 查询是否共享成功 ls /mnt/hgfs 如果显示Download(这是我共享的文件夹)&…...
用鸿蒙HarmonyOS5实现国际象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的国际象棋小游戏的完整实现代码,使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├── …...
