当前位置: 首页 > news >正文

Android 内存治理之线程

1、 前言

当我们在应用程序中启动一个线程的时候,也是有可能发生OOM错误的。当我们看到以下log的时候,就说明系统分配线程栈失败了。

java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Out of memory

这种情况可能是两种原因导致的。

  • 第一个就是系统的内存不足的时候,我们去启动一个线程。
  • 第二种就是进程内运行的线程总数超过了系统的限制。

如果是内存不足的情况,需按照堆内存治理的方式来进行解决,检查应用内存泄漏问题并优化,此情况不作为本次讨论的重点。

本次主要讨论进程内运行的线程总数超过了系统的限制所导致的情况。出现此情况时,我们就需要通过控制并发的线程总数来解决这个问题。

想要控制并发的线程数。最直接的一种方式就是利用回收的思路,也就是让我们的线程通过串行的方式来执行;一个线程执行完毕之后,再启动下一个线程。这样就能够让并发的线程总数达到一个可控的状态。

另外一种方式就是通过复用来解决,让同一个线程的实例可以被反复的利用,只创建较少的线程实例,就能完成大量的异步操作。

2、异步任务的方式对比

对比一下,在安卓平台我们比较常用的开启异步任务的方式中,有哪些是更加有利于我们进行线程总数的控制的。

2.1 Thread

从最简单的直接创建Thread的实例的方式来说起。在Java中这种方式虽然是最简单的去开启一个线程的方式,但是在实际开发中,一旦我们通过这种方式去自己创建 Thread 类的实例,并且调用 start 来开启一个线程的话,所开启的线程会非常的难以调度和管理。这种线程也就是我们平时所说的野线程。所以我们最好不要直接的创建thread类的实例。

2.2 HandlerThread

public class HandlerThread extends Thread { }

HandlerThread是Thread类的子类,对Thread做了很多便利的封装。它有自己的Loop,它能够进行消息循环,所以就能够做到通过Handler执行异步任务,也能够做到在不同的线程之间,通过Handler进行现成的通讯。我们可以利用Handler的post操作,让我们在一个线程内部串行的执行多个异步任务。从内存的角度来说,也就相当于对线程进行了复用。

2.3 AsyncTask

AsyncTask是一个相对更加轻量级,专门为了完成执行异步任务,然后返回UI线程更新UI的操作而设计的。对于我们来说,AsyncTask更像是一个任务的概念,而不是一个线程的概念。我们不需要把它当做一个线程去理解。 AsyncTask的本质,其实也是对线程和Handler的封装。

  • Android 1.6前,串行执行,原理:一个子线程进行任务的串行执行;
  • Android 1.6到2.3,并行执行,原理:一个线程数为5的线程池并行执行,但如果前五个任务执行时间过长,会堵塞后续任务执行,故不适合大量任务并发执行;
  • Android 3.0后,串行执行,原理:全局线程池进行串行处理任务;

到了Android 3.0以上版本,默认是串行执行的,但是可以结合线程值来实现有限制的并行。也可以达到一个限制线程总数的目的。

2.4 线程池

Java语言本身也为我们提供了线程池。线程池的作用就是可以管理并发数,并且能够持续的去复用线程。如果在一个应用内部的全部异步操作,全部都采用线程池的方式来开启的话,那么我们就能够管理我们所有的异步任务了。这样一来,能够大大的降低线程治理的成本。

2.5 Kotlin协程

在Kotlin中还引入了协程的概念。协程给传统的Java的异步编程带来最大的改变,就是能够让我们更加优雅的去实现异步任务。我们前面所说的这几种异步任务的执行方式,都需要我们额外的去写大量的样本代码。而Kotlin协程就能够做到让我们用写同步代码的方式去写异步代码。

在语法的层面上,协程的另一个优势就是性能方面。协程能够帮助我们用更少的线程去执行更多的并发任务。同样也降低了我们治理内存的成本。从治理内存的角度来说,用线程池接管线程或者采用协程都是很好的方式。

Android 学习笔录

Android 性能优化篇:https://qr18.cn/FVlo89
Android Framework底层原理篇:https://qr18.cn/AQpN4J
Android 车载篇:https://qr18.cn/F05ZCM
Android 逆向安全学习笔记:https://qr18.cn/CQ5TcL
Android 音视频篇:https://qr18.cn/Ei3VPD
Jetpack全家桶篇(内含Compose):https://qr18.cn/A0gajp
OkHttp 源码解析笔记:https://qr18.cn/Cw0pBD
Kotlin 篇:https://qr18.cn/CdjtAF
Gradle 篇:https://qr18.cn/DzrmMB
Flutter 篇:https://qr18.cn/DIvKma
Android 八大知识体:https://qr18.cn/CyxarU
Android 核心笔记:https://qr21.cn/CaZQLo
Android 往年面试题锦:https://qr18.cn/CKV8OZ
2023年最新Android 面试题集:https://qr18.cn/CgxrRy
Android 车载开发岗位面试习题:https://qr18.cn/FTlyCJ
音视频面试题锦:https://qr18.cn/AcV6Ap

相关文章:

Android 内存治理之线程

1、 前言 当我们在应用程序中启动一个线程的时候,也是有可能发生OOM错误的。当我们看到以下log的时候,就说明系统分配线程栈失败了。 java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Out of memory这种情况可能是两种原因导致的。…...

三、K8S之ReplicaSet

ReplicaSet 一、概述 Kubernetes最核心的功能是编排,编排操作都是依靠控制器对象来完成,高级控制器控制着基础的控制器,基础控制器再去控制Pod,Pod里面再包容器。K8S项目里API对象层级大概就是这样。 而ReplicaSet这个控制器是…...

【基础篇】四、本地部署Flink

文章目录 1、本地独立部署会话模式的Flink2、本地独立部署会话模式的Flink集群3、向Flink集群提交作业4、Standalone方式部署单作业模式5、Standalone方式部署应用模式的Flink Flink的常见三种部署方式: 独立部署(Standalone部署)基于K8S部署…...

简述什么是迭代器(Iterator)?

迭代器(Iterator)是一种设计模式,Java 中的迭代器是集合框架中的一个接口,它可以让程序员遍历集合中的元素而无需暴露集合的内部结构。使用迭代器可以遍历任何类型的集合,例如 List、Set 和 Map 等。 通过调用集合类的 iterator() 方法可以获取一个迭代器,并使用 hasNext…...

DarkGate恶意软件通过消息服务传播

导语 近日,一种名为DarkGate的恶意软件通过消息服务平台如Skype和Microsoft Teams进行传播。它冒充PDF文件,利用用户的好奇心诱使其打开,进而下载并执行恶意代码。这种攻击手段使用了Visual Basic for Applications(VBA&#xff0…...

LeetCode——动态规划篇(六)

刷题顺序及思路来源于代码随想录,网站地址:https://programmercarl.com 目录 300. 最长递增子序列 - 力扣(LeetCode) 674. 最长连续递增序列 - 力扣(LeetCode) 718. 最长重复子数组 - 力扣&#xff08…...

sql 注入(2), 文件读写 木马植入 远程控制

sql 注入 文件读写 木马植入 远程控制 一, 检测读写权限 查看mysql全局变量 SHOW GLOBAL VARIABLES LIKE %secure%secure_file_priv 空, 则任意读写secure_file_priv 路径, 则只能读写该路径下的文件secure_file_priv NULL, 则禁止读写二, 读取文件, 使用 load_file() 函数…...

求直角三角形第三点的坐标

文章目录 求直角三角形第三点的坐标1. 原理2. 数学公式3. 推导过程 求直角三角形第三点的坐标 1. 原理 已知内容有: P1、P2 两点的坐标; dis1 为 P1与P2两点之间的距离; dis2 为 P2与P3两点之间的距离; 求解: …...

【Kotlin精简】第3章 类与接口

1 简介 Kotlin类的声明和Java没有什么区别,Kotlin中,类的声明也使用class关键字,如果只是声明一个空类,Kotlin和Java没有任何区别,不过定义类的其他成员会有一些区别。实例化类不用写new,类被继承或者重写…...

关于面试以及小白入职后的一些建议

面试的本质 面试的过程是一个互相选择的过程;面试官的诉求是,了解应聘者的个人基本信息、工作态度、专业能力及其他综合能力是否与公司招聘岗位匹配;面试者的诉求是,拿下招聘岗位offer,获得工作报酬; 面试…...

Excel 从网站获取表格

文章目录 导入网站数据导入股票实时行情 用 Excel 获取网站数据的缺点:只能获取表格类的数据,不能获取非结构化的数据。 导入网站数据 转到地址之后: 实测该功能经常导致 Excel 卡死。 导入股票实时行情...

rsync 备份工具(附rsync+inotify 实时同步部署实例)

rsync 备份工具(附rsyncinotify 实时同步部署实例) 1、rsync概述1.1关于rsync1.2rsync 的特点1.3工作原理 2、rsync相关命令2.1基本格式和常用选项2.2启动和关闭rsync服务2.3下行同步基本格式2.4上行同步基本格式2.5免交互2.5.1指定密码文件2.5.2rsync-daemon方式2.…...

Java架构师缓存性能优化

目录 1 缓存的负载策略2 缓存的序列化问题3 缓存命中率低4 缓存对数据库高并发访问5 缓存数据刷新的策略5.1. 实时策略5.2. 异步策略5.3. 定时策略6 何时写缓存7 批量数据来更新缓存8 缓存数据过期的策略9 缓存数据如何恢复10 缓存数据如何迁移11 缓存冷启动和缓存预热想学习架…...

探索服务器潜能:创意项目、在线社区与其他应用

目录 一、部署自己的创意项目 优势: 劣势: 结论: 二、打造一款全新的在线社区 优势: 劣势: 结论: 三、其他用途 总结: 随着互联网的发展,越来越多的人开始拥有自己的服务器…...

「网络编程」网络层协议_ IP协议学习_及深入理解

「前言」文章内容是网络层的IP协议讲解。 「归属专栏」网络编程 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 一、IP协议简介二、IP协议报头三、IP网段划分(子网划分)四、特殊的IP地址五、IP地址的数量限制六、私有IP地址和公网IP地址七、路由八、分…...

Go 1.21 新内置函数:min、max 和 clear

max 函数 func max[T cmp.Ordered](x T, y …T) T 这是一个泛型函数,用于从一组值中寻找并返回 最大值,该函数至少要传递一个参数。在上述函数签名中,T 表示类型参数,它必须满足 cmp.Ordered 接口中定义的数据类型要求&#xff0…...

家居行业如何打破获客困局?2023重庆建博会现场,智哪儿AI营销第一课给出了答案

10月12日-14日,2023中国(重庆)建筑及装饰材料博览会(简称:2023中国重庆建博会)正在重庆国际博览中心如火如荼地进行。「智哪儿」携手2023中国重庆建博会主办方共同主办的《2023家居行业AI营销第一课&#x…...

Spring framework Day11:策略模式中注入所有实现类

前言 什么是策略模式? 策略模式(Strategy Pattern)是一种面向对象设计模式,它定义了算法族(一组相似的算法),并且将每个算法都封装起来,使得它们可以互相替换。策略模式让算法的变…...

MBBF展示的奇迹绿洲:5G的过去、此刻与未来

如果你来迪拜,一定不会错过全世界面积最大的人工岛项目,这是被称为世界第八大奇迹的棕榈岛。多年以来,这座岛从一片砂石、一棵棕榈树开始,逐步建成了整个波斯湾地区的地标,吸引着全世界游人的脚步。 纵观整个移动通信发…...

加持智慧医疗,美格智能5G数传+智能模组让就医触手可及

智慧医疗将云计算、物联网、大数据、AI等新兴技术融合赋能医疗健康领域,是提高医疗健康服务的资源利用效率,创造高质量健康医疗的新途径。《健康中国2030规划纲要》把医疗健康提升到了国家战略层面,之后《“十四五”全面医疗保障规划》等一系…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...