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

Android一个APP里面最少有几个线程

Android一个APP里面最少有几个线程

参考

https://www.jianshu.com/p/92bff8d6282f
https://www.jianshu.com/p/8a820d93c6aa

线程查看

Android一个进程里面最少包含5个线程,分别为:

  1. main线程(主线程)
  2. FinalizerDaemon线程
    终结者守护线程。对于重写了成员函数finalize的对象,它们被GC决定回收时,并没有马上被回收,而是被放入到一个队列中,等待FinalizerDaemon守护线程去调用它们的成员函数finalize,然后再被回收。
  3. FinalizerWatchdogDaemon线程
    监控终结者守护线程。用来监控FinalizerDaemon线程的执行。一旦检测那些重定了成员函数finalize的对象在执行成员函数finalize时超出一定的时候,那么就会退出VM。
  4. HeapTaskDaemon线程
    堆栈守护线程。用来执行堆栈的操作,也就是用来将那些空闲的堆内存归还给系统。
  5. ReferenceQueueDaemon线程。
    引用队列守护线程。我们知道,在创建引用对象的时候,可以关联一个队列。当被引用对象引用的对象被GC回收的时候,被引用对象就会被加入到其创建时关联的队列去。这个加入队列的操作就是由ReferenceQueueDaemon守护线程来完成的。这样应用程序就可以知道哪些被引用对象引用的对象已经被回收了。

下图是创建的一个仅有hello World!页面的工程,线程包含以下的这些。

在这里插入图片描述

刚开始我比较疑惑的是FileObserver 这个线程是否也是每个进程所必须包含的线程。后来我查看了一下Daemons创建的过程,能确定的是Android启动一个APP最少包含ReferenceQueueDaemon线程、FinalizerDaemon线程、FinalizerWatchdogDaemon线程、HeapTaskDaemon线程,以及在ActivityThread中开启的主线程。如下:

public final class Daemons {private static final int NANOS_PER_MILLI = 1000 * 1000;private static final int NANOS_PER_SECOND = NANOS_PER_MILLI * 1000;private static final long MAX_FINALIZE_NANOS = 10L * NANOS_PER_SECOND;public static void start() {ReferenceQueueDaemon.INSTANCE.start();//开启ReferenceQueueDaemon线程FinalizerDaemon.INSTANCE.start();//开启FinalizerDaemon线程FinalizerWatchdogDaemon.INSTANCE.start();//开启FinalizerWatchdogDaemon线程HeapTaskDaemon.INSTANCE.start();//开启HeapTaskDaemon线程}public static void startPostZygoteFork() {ReferenceQueueDaemon.INSTANCE.startPostZygoteFork();FinalizerDaemon.INSTANCE.startPostZygoteFork();FinalizerWatchdogDaemon.INSTANCE.startPostZygoteFork();HeapTaskDaemon.INSTANCE.startPostZygoteFork();}public static void stop() {HeapTaskDaemon.INSTANCE.stop();ReferenceQueueDaemon.INSTANCE.stop();FinalizerDaemon.INSTANCE.stop();FinalizerWatchdogDaemon.INSTANCE.stop();}...
}

1.main线程

2. ReferenceQueueDaemon线程。

代码块

3. FinalizerDaemon线程

    private static class FinalizerDaemon extends Daemon {private static final FinalizerDaemon INSTANCE = new FinalizerDaemon();private final ReferenceQueue<Object> queue = FinalizerReference.queue;private final AtomicInteger progressCounter = new AtomicInteger(0);// Object (not reference!) being finalized. Accesses may race!private Object finalizingObject = null;FinalizerDaemon() {super("FinalizerDaemon");}@Override public void runInternal() {// This loop may be performance critical, since we need to keep up with mutator// generation of finalizable objects.// We minimize the amount of work we do per finalizable object. For example, we avoid// reading the current time here, since that involves a kernel call per object.  We// limit fast path communication with FinalizerWatchDogDaemon to what's unavoidable: A// non-volatile store to communicate the current finalizable object, e.g. for// reporting, and a release store (lazySet) to a counter.// We do stop the  FinalizerWatchDogDaemon if we have nothing to do for a// potentially extended period.  This prevents the device from waking up regularly// during idle times.// Local copy of progressCounter; saves a fence per increment on ARM and MIPS.int localProgressCounter = progressCounter.get();while (isRunning()) {try {// Use non-blocking poll to avoid FinalizerWatchdogDaemon communication// when busy.FinalizerReference<?> finalizingReference = (FinalizerReference<?>)queue.poll();if (finalizingReference != null) {finalizingObject = finalizingReference.get();progressCounter.lazySet(++localProgressCounter);} else {finalizingObject = null;progressCounter.lazySet(++localProgressCounter);// Slow path; block.FinalizerWatchdogDaemon.INSTANCE.goToSleep();finalizingReference = (FinalizerReference<?>)queue.remove();finalizingObject = finalizingReference.get();progressCounter.set(++localProgressCounter);FinalizerWatchdogDaemon.INSTANCE.wakeUp();}doFinalize(finalizingReference);} catch (InterruptedException ignored) {} catch (OutOfMemoryError ignored) {}}}@FindBugsSuppressWarnings("FI_EXPLICIT_INVOCATION")private void doFinalize(FinalizerReference<?> reference) {FinalizerReference.remove(reference);Object object = reference.get();reference.clear();try {object.finalize();} catch (Throwable ex) {// The RI silently swallows these, but Android has always logged.System.logE("Uncaught exception thrown by finalizer", ex);} finally {// Done finalizing, stop holding the object as live.finalizingObject = null;}}}

4. FinalizerWatchdogDaemon线程

代码块

5. HeapTaskDaemon线程

private static class HeapTaskDaemon extends Daemon {private static final HeapTaskDaemon INSTANCE = new HeapTaskDaemon();HeapTaskDaemon() {super("HeapTaskDaemon");}// Overrides the Daemon.interupt method which is called from Daemons.stop.public synchronized void interrupt(Thread thread) {VMRuntime.getRuntime().stopHeapTaskProcessor();}@Override public void runInternal() {synchronized (this) {if (isRunning()) {// Needs to be synchronized or else we there is a race condition where we start// the thread, call stopHeapTaskProcessor before we start the heap task// processor, resulting in a deadlock since startHeapTaskProcessor restarts it// while the other thread is waiting in Daemons.stop().VMRuntime.getRuntime().startHeapTaskProcessor();}}// This runs tasks until we are stopped and there is no more pending task.VMRuntime.getRuntime().runHeapTasks();}}

查看VMRuntime的源码发现 startHeapTaskProcessor()、runHeapTasks()均是native方法。

    public native void requestConcurrentGC();public native void concurrentGC();public native void requestHeapTrim();public native void trimHeap();public native void startHeapTaskProcessor();public native void stopHeapTaskProcessor();public native void runHeapTasks();

如何查看当前项目包含几个线程

在Android studio中点击Profile 图标,点击 CPU,显示如下图,点击 Record,然后再点击 Stop,即可生成。

相关文章:

Android一个APP里面最少有几个线程

Android一个APP里面最少有几个线程 参考 https://www.jianshu.com/p/92bff8d6282f https://www.jianshu.com/p/8a820d93c6aa 线程查看 Android一个进程里面最少包含5个线程&#xff0c;分别为&#xff1a; main线程(主线程&#xff09;FinalizerDaemon线程 终结者守护线程…...

位操作解决数组的花样遍历

文章目录 题目 一、思路&#xff1a; 二、代码 总结 题目 leetcodeT289 https://leetcode.cn/problems/game-of-life/description/ 一、思路&#xff1a; 这题思路很简单&#xff0c;对每个位置按照题目所给规则进行遍历&#xff0c;判断周围网格的活细胞数即可。但是题目要求…...

【面试宝典】深入Python高级:直戳痛点的题目演示(下)

目录 &#x1f354; Python下多线程的限制以及多进程中传递参数的⽅式 &#x1f354; Python是如何进⾏内存管理的&#xff1f; &#x1f354; Python⾥⾯如何拷⻉⼀个对象&#xff1f; &#x1f354; Python⾥⾯search()和match()的区别&#xff1f; &#x1f354; lambd…...

Hive数仓操作(十七)

一、Hive的存储 一、Hive 四种存储格式 在 Hive 中&#xff0c;支持四种主要的数据存储格式&#xff0c;每种格式有其特点和适用场景&#xff0c;不过一般只会使用Text 和 ORC &#xff1a; 1. Text 说明&#xff1a;Hive 的默认存储格式。存储方式&#xff1a;行存储。优点…...

工业和自动化领域常见的通信协议

在工业和自动化领域&#xff0c;有多种常见的通信协议&#xff0c;主要用于设备间的通信、数据传输和控制。 Modbus&#xff1a; 类型&#xff1a;串行通信协议用途&#xff1a;广泛用于工业自动化设备间的通信&#xff0c;如PLC、传感器和执行器。优点&#xff1a;简单、开放且…...

连夜爆肝收藏各大云服务新老用户优惠活动入口地址(内含免费试用1个月的地址),适用于小白,大学生,开发者,小企业老板....

具体请前往&#xff1a;云服务器优惠活动入口大全--收藏各主流云厂商的云服务器等系列产品的优惠活动入口&#xff0c;免费试用1个月活动入口&#xff0c;让新老用户都能根据使用场景和身份快速锁定优惠权益 经济下滑&#xff0c;被优化增多&#xff0c;大学生就业难&#xff0…...

SpringBoot+Redis+RabbitMQ完成增删改查

各部分分工职责 RabbitMQ负责添加、修改、删除的异步操作 Redis负责数据的缓存 RabbitMQ里面角色职责简单描述 RabbitMQ里面有几个角色要先分清以及他们的对应关系&#xff1a; 交换机、队列、路由键 交换机和队列是一对多 队列和路由键是多对多 然后就是消息的发送者&…...

【系统集成中级】线上直播平台开发项目质量管理案例分析

【系统集成中级】线上直播平台开发项目质量管理案例分析 一、案例二、小林在项目质量管理中存在的问题&#xff08;一&#xff09;计划阶段缺失&#xff08;二&#xff09;测试用例编制与执行问题&#xff08;三&#xff09;质量管理流程问题&#xff08;四&#xff09;质量保证…...

浪潮信息领航边缘计算,推动AI与各行业深度融合

在9月20日于安徽盛大召开的浪潮信息边缘计算合作伙伴大会上&#xff0c;浪潮信息指出&#xff0c;未来的计算领域将全面融入AI技术&#xff0c;特别是在企业边缘侧&#xff0c;智能应用特别是生成式人工智能应用正在迅速普及&#xff0c;这一趋势正引领边缘计算向边缘智算的方向…...

Koa2项目实战3 (koa-body,用于处理 HTTP 请求中的请求体)

以用户注册接口为例&#xff0c;需要在请求里携带2个参数&#xff1a;用户名&#xff08;user_name&#xff09;和密码&#xff08;password&#xff09;。 开发者需要在接口端&#xff0c;解析出user_name 、password。 在使用Koa开发的接口中&#xff0c;如何解析出请求携带…...

复盘20241012

1、 classpath "com.android.tools.build:gradle:8.5.1" 的版本 与distributionUrlhttps\://services.gradle.org/distributions/gradle-8.9-bin.zip的对应规则&#xff1a; Execution failed for task :app:compileDebugKotlin. 解决方案 切换 setting --> ot…...

泊松流负载均衡控制

目录 泊松流负载均衡控制 一、到达率λ 二、服务率μ 三、泊松流负载均衡控制 泊松流负载均衡控制 在探讨泊松流负载均衡控制时,我们主要关注的是到达率λ和服务率μ这两个核心参数。以下是对这两个参数及其在泊松流负载均衡控制中作用的详细解释: 一、到达率λ 定义:…...

3D打印矫形器市场报告:未来几年年复合增长率CAGR为10.8%

3D 打印矫形器是指使用 3D 打印技术制作的定制外部支撑装置。它们有助于稳定、引导、缓解或纠正肌肉骨骼状况&#xff0c;并根据个体患者的解剖结构进行设计&#xff0c;通常使用 3D 扫描和建模技术。3D 打印在矫形器方面的主要优势是能够生产精确适合患者解剖结构的定制装置&a…...

Richtek立锜科技线性稳压器 (LDO) 选型

一、什么是LDO? LDO也可称为低压差线性稳压器&#xff0c;适合从较高的输入电压转换成较低输出电压的应用&#xff0c;这种应用的功率消耗通常不是很大&#xff0c;尤其适用于要求低杂讯、低电流和输入、输出电压差很小的应用环境。 二、LDO的特性 LDO透过控制线性区调整管…...

Leetcode 前 k 个高频元素

使用最小堆算法来解决这道题目&#xff1a;相当于有一个容量固定为K的教室&#xff0c;只能容纳 K 个人&#xff0c;学生们逐个逐个进入该教室&#xff0c;当教室容量达到K人之后&#xff0c;每次进入一个新的学生后&#xff0c;我们将分数最低的学生(类似本题中的频率最低元素…...

[LeetCode] 面试题01.02 判定是否互为字符重拍

题目描述&#xff1a; 给定两个由小写字母组成的字符串 s1 和 s2&#xff0c;请编写一个程序&#xff0c;确定其中一个字符串的字符重新排列后&#xff0c;能否变成另一个字符串。 示例 1&#xff1a; 输入: s1 "abc", s2 "bca" 输出: true 示例 2&am…...

数据结构-4.5.KMP算法(旧版上)-朴素模式匹配算法的优化

朴素模式匹配算法最坏的情况&#xff1a; 一.实例&#xff1a; 第一轮匹配失败&#xff0c;开始下一轮的匹配&#xff1a; 不断的操作&#xff0c;最终匹配成功&#xff1a; 如上述图片所述&#xff0c;朴素模式匹配算法会导致时间开销增加&#xff0c; 优化思路&#xff1a;主…...

STM32 QSPI接口驱动GD/W25Qxx配置简要

STM32 QSPI接口GD/W25Qxx配置简要 &#x1f4dd;本篇会具体涉及介绍Winbond&#xff08;华邦&#xff09;和GD(兆易创新) NOR flash相关型号指令差异。由于网络上可以搜索到很多相关QSPI相关知识内容&#xff0c;不对QSPI通讯协议做深度解析。 &#x1f516;首先确保所使用的ST…...

UCI-HAR数据集深度剖析:训练仿真与可视化解读

在本篇文章中&#xff0c;我们将深入探讨如何使用Python对UCI人类活动识别&#xff08;HAR&#xff09;数据集进行分割和预处理&#xff0c;以及运用模型网络CNN对数据集进行训练仿真和可视化解读。 一、UCI-HAR数据集分析及介绍 UCI-HAR数据集是一个公开的数据集&#xff0c…...

牛客SQL练习详解 06:综合练习

牛客SQL练习详解 06&#xff1a;综合练习 SQL34 统计复旦用户8月练题情况SQL35 浙大不同难度题目的正确率SQL39 21年8月份练题总数 叮嘟&#xff01;这里是小啊呜的学习课程资料整理。好记性不如烂笔头&#xff0c;今天也是努力进步的一天。一起加油进阶吧&#xff01; SQL34 统…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...