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

Android 性能优化:内存优化(理论篇)

内存作为App程序运行最重要的资源之一,需要运行过程中做到合理的资源分配与回收,不合理的内存占用轻则使得用户应用程序运行卡顿、ANR、黑屏,重则导致用户应用程序发生 OOM(out of memory)崩溃。喜马直播随着近些年的业务迭代功能不断完善玩法丰富,需要在各种机器资源上保持优秀的流畅性和稳定性,内存优化是必须要重视的环节。

从目前的内存水位和APM建设入手,梳理统计规则和项目真实内存水位,在代码和业务多方面熟悉和归因,搭配工具建设和使用为抓手,最后通过内存专项治理将应用的 OOM优化到合理水位。

限于篇幅和功能性,文章总共分为理论篇实践篇两个部分。

写这篇文章动机,主要是工作中进行内存优化专项,便于将以往琐碎的内存知识和优化思路整合,所以有了这篇文章,感谢前人的经验。谨以此篇文章记录工作思路及基础知识,温故知新。

思维导图

在这里插入图片描述

内存基础知识

Android 最新系统都运行在ART虚拟机上,基于 Linux 内核实现,Linux的内存管理哲学是:Free memory is wasted memory。即内存没有得到充分利用就是在浪费内存。因此 Linux 希望尽可能多的使用内存,较少磁盘 IO 。Android 系统继承了 Linux 的优点,同样是尽最大限度使用原则。

与Linux不同的是 Android 侧重于可能多的缓存进程以提高应用启动和切换速度。即,Android系统会在内存中尽量的长时间的保持应用进程,直到系统分配内存不足时才会去根据进程优先级、内存代销等条件回收进程。这些保留在内存中的进程通常不会影响系统整体的运行速度,反而会在用户再次激活这些进程时,加快进程的启动速度。

在内存管理上,JVM拥有垃圾内存回收的机制,自身会在虚拟机层面自动分配和释放内存,因此不需要像使用C/C++一样在代码中分配和释放某一块内存。Android系统的内存管理原理基础就是JVM,通过new关键字来为对象分配内存,内存的释放由GC来回收。并且Android系统在内存管理上有一个 Generational Heap Memory模型,当内存达到某一个阈值时,系统会根据不同的规则自动释放可以释放的内存。即便有了内存管理机制,但是,如果不合理地使用内存,也会造成一系列的性能问题,比如 内存泄漏、内存抖动、短时间内分配大量的内存对象,接下来详细记录下Android内存管理模式及知识点。

Jvm内存分配模型

JVM 将整个内存划分为了几块:

  1. 方法区:存储类信息、常量、静态变量等。(所有线程共享)
  2. 虚拟机栈:存储局部变量表、操作数栈等。
  3. 本地方法栈:不同于虚拟机栈为 Java 方法服务、它是为 Native 方法服务的。
  4. 堆:内存最大的区域,每一个对象实际分配内存都是在堆上进行分配的,,而在虚拟机栈中分配的只是引用,这些引用会指向堆中真正存储的对象。此外,堆也是垃圾回收器(GC)所主要作用的区域,并且,内存泄漏也都是发生在这个区域。(所有线程共享)
  5. 程序计数器:存储当前线程执行目标方法执行到了第几行。

Android内存分配

Android Runtime有两种虚拟机,Dalvik 和 ART,实际上就是一块匿名共享内存。Android虚拟机仅仅只是把它封装成一个 mSpace由底层C库来管理,并且仍然使用libc提供的函数malloc和free来分配和释放内存

大多数静态数据会被映射到一个共享的进程中。常见的静态数据包括Dalvik Code、app resources、so文件等等。Android通过显示分配共享内存区域(如Ashmem或者Gralloc)来实现动态RAM区域能够在不同进程之间共享的机制。例如,Window Surface在App和Screen Compositor之间使用共享的内存,Cursor Buffers在Content Provider和Clients之间共享内存。下面简单总结下我理解的堆结构:

Dalvik

Linear Alloc 、 Zygote Space 和 Alloc Space

ART

(重点汇总下)

  • Zygote Space: 包含由 Zygote 进程预加载并在所有应用程序之间共享的对象。

  • Allocation Space:用于存储应用程序在运行时创建的对象,主要的GC工作区域,为每个进程独自使用。

  • Non-Moving Space:存储不需要移动的对象,如 ART 内部数据结构,和Dalvik中的Linear Alloc类似。

  • Large Object Space :用于存储大对象(通常大于 12KB)使用单独的分配策略和GC机制。

  • Region Space :用于新生代对象的分配和管理,是离散地址的集合,使用更高效的垃圾回收机制。

  • Image Space:包含预编译的系统类和应用程序类,从预生成的映像文件中内存映射而来,在Zygote和其他应用程序进程之间共享,不参与GC。

Android系统的第一个虚拟机由Zygote进程创建并且只有一个Zygote Space。但是当Zygote进程在fork第一个应用程序进程之前,会将已经使用的那部分堆内存划分为一部分,还没有使用的堆内存划分为另一部分,也就是Allocation Space。但无论是应用程序进程,还是Zygote进程,当他们需要分配对象时,都是在各自的Allocation Space堆上进行

单进程内存上限

Android 系统的 Java虚拟机会对单个进程使用的最大内存做限制,该属性值定义在/system/build.prop文件中,厂商一般会根据设备自身内存大小来设定这个值,不同的设备分配给APP的最大可用内存是不相同的。进程启动时,系统会先为APP分配一定的内存空间,当分配的内存快要耗尽时,系统会再次为App 分配更多的内存,但是每个APP都有内存使用上限,一旦进程分配了最大可用内存后,内存依然不足则会直接抛出OOM异常,终止程序的运行。可以通过调用 getMemoryClass() 向系统查询此数值。此方法返回一个整数,表示应用堆的可用兆字节数。

内存垃圾回收

当进程使用内存达到设定的阈值时,就会触发虚拟机的GC机制,虽然新一代的ART对于通过分代垃圾回收和高效的内存分配机制,ART 能够更加高效地使用内存,减少内存碎片和内存泄漏等方面的优化,但是GC的时候,还是会导致 STW (Stop The World),所以为了提升程序性能,有必要进行内存优化。下边列举一下Java的内存回收算法。

标记清除算法

标记清除算法是一种垃圾回收算法,用于管理动态分配的内存。它的主要思想是,遍历整个堆,标记所有被引用的对象,当某个对象不再被程序所引用时,它就可以被认为是“垃圾”,并被回收以便后续的内存分配。 优缺点:自动管理动态分配的内存,但是清除后可能导致大量的内存碎片,降低堆利用率。

复制算法

复制算法是一种将内存分为两个区域的算法,其中一个区域用于存储活动对象,另一个区域用于存储不再使用的对象。 优缺点:运行效率高,但是浪费一半空间,代价较高。

标记整理算法

标记整理算法是标记清除算法和复制算法的结合,其工作原理是先标记出不再使用的对象,再整理内存使得活动对象的内存分配连续,优缺点:解决了标记清除算法导致的内存碎片问题,但是也产生了一些问题,由于进行了两次扫描,增加了时间开销。 相较其他垃圾回收算法,速度较慢,不适合新生代场景,并且标记整理算法的效率也受内存使用情况影响,效率不稳定等问题。

分代收集算法

分代回收算法是一种将内存分为几个代的算法,并对每个代进行不同的回收策略,这里就需要借一张图了,一图胜千言

image.png

新创建的对象 , 放在年轻代内存块中 , 开始时放在 Eden 区域 , 当 Eden 区域存满后 , 会将存活的对象转移到 From 区域 和 To 区域,对象每经过一次 GC 垃圾回收 , 其年龄就会加 1 ; 当年龄到达虚拟机设置的阈值之后 , 就会被放入老年代内存块中 ,持久代内存区域,主要存放着类加载器加载的Class和常量池等对象。

image.png

  • 年轻代内存区域的垃圾回收器 : Minor GC (Serial,ParNew 和 Parallel Scavenge)

  • 老年代内存区域的垃圾回收器 : Major GC (CMS ,Serial Old和 Parallel Old)

  • 整个内存区域的垃圾回收器 : Full GC

持久代内存区域的内存不回收 ;年轻代内存区域与老年代内存区域的垃圾回收机制不同的。

Serial ParNew都是 使用的复制算法,主要在年轻代中收集要回收的内存,但是Serial是单线程串行,而ParNew则是多线程运行。

CMS Concurrent Mark Sweep ,并发标记清除收集器,采用标记清除算法,gc过程,用户线程仅做最短停顿,具体流程如下:

  • 初始标记 : 标记与 GC Roots 有引用链的对象 ; 该操作速度快 , 该步骤需要暂停用户线程。

  • 并发标记 : GC Roots 追踪,从初始标记结果集合中标记出存活对象,不能保证所有的存活对象都被标记 ; 该步骤与应用程序并发执行。

  • 重新标记 : 上一步并发标记 GC 线程与用户程序并发期间的标记有部分变化 , 修正这部分标记信息之后暂停用户线程 开始标记,该暂停操作要比初始标记步骤暂停时间长。

  • 并发清除 : 回收所有 GC Roots 不可达对象

CMS的优点是,并发收集,低停顿。有一个明显缺点就是因为采用了“标记-清除”算法,最后会出现大量碎片,有可能会出现在某一个时刻,当有大对象生成,不得不进行一次Full GC来解决这个问题。为了解决该问题CMS有一个参数-XX:UseCmsCompactAtFullCollection来解决因为空间不足进行Full GC。这个参数默认开启,用于在CMS收集器顶不住要进行Full GC是开启内存碎片合并整理的过程,内存整理过程是无法并发的,因此就会耗时。同时还有一个参数是-XX:CMSFullGCsBeforeCompaction,这个参数是用于执行多次不压缩的GC后,跟着来一次压缩的(默认是0,表示每次进入Full GC都进行碎片整理)。

G1收集器

Garbage-First收集器:并行和并发,分代收集。 G1和其他收集器不同的是,其他收集器收集范围都是整个新生代和老年代,而G1不再是这样。使用G1收集器的时候,Java堆分为多个大小相等的区域(Region),虽然也保留了新生代和老年代的概念,但是不再是物理隔离了,他们都是一部分Region的集合(这些Region不一定是连续的)。G1保留了Eden和Survivor的比例也是8:1:1。

ZGC

JDK11引入的ZGC收集器,在物理和逻辑上已经没有新/老年代的概念了,会分为一个个page,当进行GC操作时候会对page进行压缩,因此没有碎片问题,只能在64位linux上使用。

  • 可以达到10ms以内的停顿要求
  • 支持TB级别的内存
  • 堆内存变大后停顿时间还是在10ms以内

Java 引用类型

既然上边列举了主要的回收算法,这里简单带过一下引用类型,也是内存优化过程中,经常使用到的知识点:

  • 强引用 :强引用是 Java 中最常见的引用类型,当对象具有强引用时,它永远不会被垃圾回收。只有在程序结束或者手动将对象设置为 null 时,才会释放强引用,像常用的 new 方式。
  • 软引用 :当 Java 堆内存不足时,软引用可能会被回收,以腾出内存空间。如果内存充足,则软引用可以继续存在,使用SoftReference创建,gc的时候可能并不会释放软引用持有对象。
  • 弱引用 :在垃圾回收器线程扫描它所管辖的内存区域的过程中,发现具有弱引用的对象,不管当前内存空间是否足够,都会回收它的内存。
  • 虚引用 : 只能用于跟踪即将对被引用对象进行的收集。虚拟机必须与ReferenceQueue类联合使用。因为它能够充当通知机制。

内存优化的必要性

经过上述基础知识的分析,我们认识到内存在手机侧的宝贵和重要性,安卓系统对每个应用程序都有一定的内存限制,当应用程序的内存超过了上限,就会出现 OOM,造成App的异常退出。

因此,要改善系统的运行效率、改善用户体验、降低系统资源占用、延长电池寿命、降低系统故障的危险。Android通过内存优化,可以减少系统内存使用 提高应用后台运行存活率,让系统更加流畅,秒开率更高,减少系统GC次数,减少页面卡顿率,降低内存泄漏率,从而提高App的整体体验和功耗优化。

内存优化思路及SOP

在这里插入图片描述

数据收集及水位分析

关于性能或功耗方面的优化问题,都要先做到摸清大盘数据,特别是我这种新的公司,新的APM系统的,一定要摸清APM上报原理和逻辑,并且输出自己的文档,好记性不如烂笔头。

查看内存泄露、内存溢出和线程超标等方面的数据后,动手改代码前要确定好优化后的目标水位是多少,定好里程碑,及时同步领导,避免大方向错误。

借助工具排查问题

在线上大盘水位摸清之后,比如我们是基于Koom进行了魔改,就可以将上报的内存泄露问题统一汇总并解决,但是内存的水位偏高和内存抖动问题,就需要借助本地检测工具进行排查。下篇具体汇总下,通过工具查看问题。 比如图片使用方面,可以使用 Hook native bitmap (新版本都是用Native内存,暂不考虑 8.0 之前的版本情况了)检测图片在退出页面后,是否清理完成。

问题优化

针对不同类型问题需要使用不同的方式,比如内存抖动问题,存在一些大对象或者过多小对象的情况,可能存在频繁创建对象等问题。如果存在内存泄露等问题,则需要根据堆栈调用链,排查那些代码存在纰漏。针对问题优化后,做好兜底策略,并后续关注新版本是否有新的上报。

长效治理策略

问题如果解决后,可以将常见的内存泄露问题进行汇总,在排查问题过程中,使用到的工具及操作流程进行整理,汇总成内存优化SOP,可以在组内进行技术分享,提高团队的内存优化意识。

关于长期卡口,可以尝试在Git Hook的办法,针对提交的代码进行监控,如果出现内存泄露的写法阻止代码提交,并展示警告信息。

参考文章

Android性能优化之内存优化 - JsonChao

分代收集算法

深入探索 Android 内存优化(炼狱级别-上)

深入探索 Android 内存优化(炼狱级别-下)

相关文章:

Android 性能优化:内存优化(理论篇)

内存作为App程序运行最重要的资源之一,需要运行过程中做到合理的资源分配与回收,不合理的内存占用轻则使得用户应用程序运行卡顿、ANR、黑屏,重则导致用户应用程序发生 OOM(out of memory)崩溃。喜马直播随着近些年的业…...

Flink四大基石之窗口(Window)使用详解

目录 一、引言 二、为什么需要 Window 三、Window 的控制属性 窗口的长度(大小) 窗口的间隔 四、Flink 窗口应用代码结构 是否分组 Keyed Window --键控窗 Non-Keyed Window 核心操作流程 五、Window 的生命周期 分配阶段 触发计算 六、Wi…...

Easy Excel 通过【自定义批注拦截器】实现导出的【批注】功能

目录 Easy Excel 通过 【自定义批注拦截器】实现导出的【批注】功能需求原型:相关数据:要导出的对象字段postman 格式导出对象VO 自定义批注拦截器业务代码: 拦截器代码解释:详细解释:格式优化: Easy Excel…...

PHP 去掉特殊不可见字符 “\u200e“

描述 最近在排查网站业务时,发现有数据匹配失败的情况 肉眼上完全看不出问题所在 当把字符串 【M24308/23-14F‎】复制出来发现 末尾有个不可见的字符 使用删除键或左右移动时才会发现 最后测试通过 var_dump 打印 发现这个"空字符"占了三个长度 &#xf…...

Flume和kafka的整合:使用Flume将日志数据抽取到Kafka中

文章目录 1、Kafka作为Source【数据进入到kafka中,抽取出来】2、kafka作为Sink 【数据从别的地方抽取到kafka里面】 1、Kafka作为Source【数据进入到kafka中,抽取出来】 kafka源 --> memory --> 控制台: a1.sources r1 a1.sinks k1…...

Flutter:启动屏逻辑处理02:启动页

启动屏启动之后&#xff0c;制作一个启动页面 新建splash&#xff1a;view 视图中只有一张图片sliding.png就是我们的启动图 import package:flutter/material.dart; import package:get/get.dart; import index.dart; class SplashPage extends GetView<SplashController…...

【MySQL】自动刷新flush privileges命令

在 MySQL 中&#xff0c;执行 FLUSH PRIVILEGES 命令的主要作用是使权限表中的更改立即生效。下面是关于这个命令的一些关键点&#xff1a; 1. 什么是 FLUSH PRIVILEGES 当你使用 SET PASSWORD 或其他 SQL 语句直接修改了用户的密码或权限&#xff08;例如&#xff0c;使用 U…...

2024免费天气接口(无废话版)

免费接口1&#xff1a;http://t.weather.sojson.com/api/weather/city/101030100 免费接口2&#xff1a;http://t.weather.itboy.net/api/weather/city/101030100 至于后面那个城市编码 请自行查询&#xff1a;如图 注意&#xff01;&#xff01;&#xff01; 点击下载时 可能…...

fpga 时序分析基础

目录 触发器的动态参数 同步时序电路分析 1. 时钟脉冲的特性 2. 同步时序电路分析 Timing Analyzer的应用 异步时序与亚稳态问题 时序分析就是对时序电路进行时序检查&#xff0c;通过分析电路中所有寄存器之间的路径延迟以检查电路的传输延迟是否会导致触发器的建立时间…...

Laravel8.5+微信小程序实现京东商城秒杀方案

一、商品秒杀涉及的知识点 鉴权策略封装掊口访问频次限制小程序设计页面防抖接口调用订单创建事务使用超卖防御 二、订单库存系统方案&#xff08;3种&#xff09; 下单减库存 优点是库存和订单的强一致性&#xff0c;商品不会卖超&#xff0c;但是可能导致恶意下单&#xff…...

Git——本地仓库链接并推送到多个远程仓库

步骤 1. 新建仓库init 或 删除已有仓库远程链接 // 1.新建init git init// 2.已有仓库&#xff0c;查看链接的远程仓库 git remote -v// 3.已有远程连接仓库&#xff0c;需要删除连接 git remote rm origin(或对应远程仓库名) 2.新建远程仓库 在gitee、github等托管平台创建…...

llama-factory 系列教程 (七),Qwen2.5-7B-Instruct 模型微调与vllm部署详细流程实战

文章目录 介绍llama-factory 安装装包下载模型 微调模型数据集训练模型 微调后的模型推理 介绍 时隔已久的 llama-factory 系列教程更新了。本篇文章是第七篇&#xff0c;之前的六篇&#xff0c;大家酌情选看即可。 因为llama-factory进行了更新&#xff0c;我前面几篇文章的实…...

Spring Boot的理解

一、什么是Spring Boot? Spring Boot是一个用于构建基于Spring框架的应用程序的开源框架。它简化了Spring应用程序的开发过程&#xff0c;使开发者能够更容易地创建独立运行的、生产级别的Spring应用程序。Spring Boot提供了许多功能和约定&#xff0c;可以帮助开发者快速搭建…...

QT QFormLayout控件 全面详解

本系列文章全面的介绍了QT中的57种控件的使用方法以及示例,包括 Button(PushButton、toolButton、radioButton、checkBox、commandLinkButton、buttonBox)、Layouts(verticalLayout、horizontalLayout、gridLayout、formLayout)、Spacers(verticalSpacer、horizontalSpacer)、…...

系统性能定时监控PythonLinux

系统性能定时监控 1.系统监控概述 ⽤Python来编写脚本简化⽇常的运维⼯作是Python的⼀个重要⽤途。在Linux下&#xff0c;有许多系统命令可以让我们时刻监控系统运⾏的状态&#xff0c;如 ps &#xff0c; top &#xff0c; free 等等。要获取这些系统信息&#xff0c;Python…...

python学习——列表的相关操作

在 Python 中&#xff0c;列表&#xff08;list&#xff09;是一种非常灵活的数据结构&#xff0c;可以用来存储一系列的元素。以下是列表的一些常见操作&#xff1a; 文章目录 创建列表访问元素修改元素列表切片添加元素删除元素列表推导式其他操作pop基本用法指定索引使用场…...

HTML CSS 魔法秀:打造翻转卡片登录注册页面

这段 HTML 和 CSS 代码创建了一个具有翻转卡片效果的登录和注册页面。下面是对重点标签和 CSS 样式的解释和总结&#xff1a; 一键复制 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"…...

Web day04 SpringBoot

目录 1.Spring概念&#xff1a; 2. spring程序快速入门&#xff1a; 3.HTTP协议&#xff1a; 特点&#xff1a; 基于TCP 协议&#xff1a; 基于请求响应模型&#xff1a; HTTP协议是无状态协议&#xff1a; 请求协议&#xff1a;为浏览器向服务器发出的消息 获取请求数据…...

selinux和防火墙实验

1 、 selinux 的说明 SELinux 是 Security-Enhanced Linux 的缩写&#xff0c;意思是安全强化的 linux 。 SELinux 主要由美国国家安全局&#xff08; NSA &#xff09;开发&#xff0c;当初开发的目的是为了避免资源的误用。 系统资源都是通过程序进行访问的&#xff0c;如…...

ClamAV 在 CentOS 的开发版本 `clamav-devel`

是的&#xff0c;ClamAV 在 CentOS 上有开发版本&#xff08;通常称为 clamav-devel&#xff09;&#xff0c;它包含了开发 ClamAV 应用程序所需的头文件和库文件。以下是如何在 CentOS 上安装 ClamAV 及其开发版本的步骤。 ### 1. **安装 EPEL 仓库** ClamAV 通常在 EPEL&am…...

C++《二叉搜索树》

在初阶数据结构中我学习了树基础的概念以及了解了顺序结构的二叉树——堆和链式结构二叉树该如何实现&#xff0c;那么接下来我们将进一步的学习二叉树&#xff0c;在此会先后学习到二叉搜索树、AVL树、红黑树&#xff1b;通过这些的学习将让我们更易于理解后面set、map、哈希等…...

⭐️ GitHub Star 数量前十的工作流项目

文章开始前&#xff0c;我们先做个小调查&#xff1a;在日常工作中&#xff0c;你会使用自动化工作流工具吗&#xff1f;&#x1f64b; 事实上&#xff0c;工作流工具已经变成了提升效率的关键。其实在此之前我们已经写过一篇博客&#xff0c;跟大家分享五个好用的工作流工具。…...

uni-app中的样式尺寸单位,px,rpx,vh,vw

uni-app 支持less、sass、scss、stylus等预处理器。 尺寸单位 uni-app 支持的通用 css 单位包括 px、rpx px 即屏幕像素rpx 即响应式 px&#xff0c;一种根据屏幕宽度自适应的动态单位。以 750 宽的屏幕为基准&#xff0c;**750rpx 恰好为屏幕宽度。**屏幕变宽&#xff0c;r…...

跳表(Skip List)

跳表&#xff08;Skip List&#xff09; 跳表是一种用于快速查找、插入和删除的概率型数据结构&#xff0c;通常用于替代平衡二叉搜索树&#xff08;如 AVL 树或红黑树&#xff09;。跳表通过在有序链表的基础上增加多层索引&#xff0c;使得查找操作的平均时间复杂度降低&…...

103.【C语言】数据结构之建堆的时间复杂度分析

1.向下调整的时间复杂度 推导 设树高为h 发现如下规律 按最坏的情况考虑(即调整次数最多) 第1层,有个节点,最多向上调整h-1次 第2层,有个节点,最多向上调整h-2次 第3层,有个节点,最多向上调整h-3次 第4层,有个节点,最多向上调整h-4次 ... 第h-1层,有个节点,最多向上调整1次 第…...

数字信号处理实验报告四:IIR数字滤波器设计及软件实现

1.实验目的 (1)熟悉用双线性变换法设计IIR数字滤波器的原理与方法; (2)学会调用MATLAB信号处理工具箱中滤波器设计函数(或滤波器设计分析工具fdatool)设计各种IIR数字滤波器,学会根据滤波需求确定滤波器指标参数。 (3)掌握IIR数字滤波器的MATLAB实现方法。 (3)…...

Flutter:encrypt插件 AES加密处理

1、pubspec.yaml导入插件 cupertino_icons: ^1.0.8 # 密码加密 encrypt: 5.0.3encrypt封装 import package:encrypt/encrypt.dart; /// 加密类 class EncryptUtil {static final EncryptUtil _instance EncryptUtil._internal();factory EncryptUtil() > _instance;Encrypt…...

软银集团孙正义再度加码OpenAI,近屿智能专注AI人才培养

11月28日凌晨&#xff0c;全球最大财经CNBC报道&#xff0c;软银集团创始人兼CEO孙正义再次向人工智能领域的领军企业OpenAI投资了15亿美元。软银对OpenAI的投资已不是首次。就在上个月&#xff0c;软银已在OpenAI的上一轮融资中注入了5亿美元的资金。但他一直寻求获得OpenAI更…...

windows11下的Ubuntu(WSL)中安装界面测试ROS

症状&#xff1a;我在WSL(Ubuntu)中我自己的用户名下面安装好了ROS,输入命令行能用&#xff0c;就是不弹出窗口。 首先到windows应用商店安装Ubuntu,我这里安装的是20.04,然后安装对应的ROS&#xff08;Noetic版本&#xff09;. 然后windows安装VcXsrv. Ubuntu安装xfce4。 …...

Stable Diffusion 3详解

&#x1f33a;系列文章推荐&#x1f33a; 扩散模型系列文章正在持续的更新&#xff0c;更新节奏如下&#xff0c;先更新SD模型讲解&#xff0c;再更新相关的微调方法文章&#xff0c;敬请期待&#xff01;&#xff01;&#xff01;&#xff08;本文及其之前的文章均已更新&…...

【CSS】设置文本超出N行省略

文章目录 基本使用 这种方法主要是针对Webkit浏览器&#xff0c;因此可能在一些非Chrome浏览器中不适用。 基本使用 例如&#xff1a;设置文本超出两行显示省略号。 核心代码&#xff1a; .ellipsis-multiline {display: -webkit-box; -webkit-box-orient: vertical; /* 设置…...

Python绘画:蛋糕

Python绘画&#xff1a;蛋糕 &#x1f438; 前言 &#x1f438;&#x1f40b; 效果图 &#x1f40b;&#x1f409; 代码 &#x1f409; &#x1f335;&#x1f332;&#x1f333;&#x1f334;&#x1f33f;&#x1f340;☘️&#x1f331;&#x1f343;&#x1f38b;&#x1f…...

使用wget在清华镜像站下载Anaconda报错ERROR 403: Forbidden.

问题描述 使用wget在清华镜像站下载Anaconda报错ERROR 403: Forbidden. Resolving mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)… 101.6.15.130, 2402:f000:1:400::2 Connecting to mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)|101.6.15…...

道可云人工智能元宇宙每日资讯|第三届京西地区发展论坛成功召开

道可云元宇宙每日简报&#xff08;2024年11月27日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 工信部等十二部门印发《5G规模化应用“扬帆”行动升级方案》 11月25日&#xff0c;工业和信息化部等十二部门印发《5G规模化应用“扬帆”行动升级方案》。《方案》…...

web安全之信息收集

在信息收集中,最主要是就是收集服务器的配置信息和网站的敏感信息,其中包括域名及子域名信息,目标网站系统,CMS指纹,目标网站真实IP,开放端口等。换句话说,只要是与目标网站相关的信息,我们都应该去尽量搜集。 1.1收集域名信息 知道目标的域名之后,获取域名的注册信…...

Google Earth Engine APP(GEE) ——基于多种机器学习多源遥感不同变量组合下的森林地表生物量模型预测APP

目录 Arguments: Returns: ui.Select Arguments: Returns: ui.Chart Arguments: Returns: ui.Chart Arguments: Returns: Classifier Arguments: Returns: Classifier Arguments: Returns: Classifier 本代码的主要功能是将我们提前准备好的森林生物量样本点上传到…...

Redis开发02:redis.windows-service.conf 默认配置文件解析与注解

文件位置&#xff1a;redis安装目录下的 redis.windows-service.conf &#xff0c;存放了redis服务的相关配置&#xff0c;下面列举出默认配置的含义&#xff1a; 配置项含义bind 127.0.0.1限制 Redis 只监听本地回环地址&#xff0c;意味着只能从本地连接 Redis。protected-m…...

webrtc 3A移植以及实时处理

文章目录 前言一、交叉编译1.Pulse Audio webrtc-audio-processing2.交叉编译 二、基于alsa进行实时3A处理1.demo源码2.注意项3.效果展示 总结 前言 由于工作需要&#xff0c;硬件3A中的AEC效果实在太差&#xff0c;后面使用SpeexDSP的软3A&#xff0c;效果依旧不是很好&#…...

Android so库的编译

在没弄明白so库编译的关系前,直接看网上博主的博文,常常会觉得云里雾里的,为什么一会儿通过Android工程cmake编译,一会儿又通过NDK命令去编译。两者编译的so库有什么区别? android版第三方库编译总体思路: 对于新手小白来说搞明白上面的总体思路图很有必…...

Reachy 2,专为AI与机器人实验室打造的卓越开源双臂移动操作平台!

近期&#xff0c;花粉机器人&#xff08;POLLEN ROBOTICS&#xff09;隆重推出Reachy 2仿生机器人——下一代开源操作平台&#xff0c;为AI与机器人实验室带来理想的双臂移动操作科研平台&#xff01; Reachy 2的仿生性&#xff1a; 》拥有两个基于Maxon无刷电机的仿生7自由度…...

Jest 测试异步函数

异步编程的发展历史 异步函数,就不用我描述了,JS是单线程的,所以没有办法处理异步问题,但是可以通过其他的机制实现 回调函数 例如,我们写一个定时器,在函数fetchData中,有一个延时处理的函数,但是,你有不能等他,如果他是一年呢? 所以,我们给他一个回调函数,来等他执行完返回处…...

linux安全管理-防火墙配置

1. 开启系统防火墙 1、检查内容 检查操作系统是否开启防火墙&#xff1b; 2、配置要求 操作系统开启防火墙&#xff1b; 3、配置方法 systemctl status firewalld ##查看系统防火墙运行状态 systemctl start firewalld ##启动防火墙 systemctl restart firewalld ##重启防火墙…...

Blender 运行python脚本

Blender 运行python脚本 步骤 1&#xff1a;打开 Blender 首先&#xff0c;打开 Blender 软件。你可以从官方网站 [blender.org]( 下载最新的 Blender 版本&#xff0c;并按照安装向导进行安装。 步骤 2&#xff1a;打开“文本编辑器”面板 在 Blender 的默认布局中&#xff…...

Three.js CSS2D/CSS3D渲染器

在Three.js开发过程中&#xff0c;有时需要将 HTML 元素与 Three.js 渲染的 3D 场景相结合&#xff0c;这就需要用到 CSS2DRenderer 和 CSS3DRenderer。本文将详细介绍这两种渲染器的原理及其应用 一、CSS2DRenderer 渲染器 概述 CSS2DRenderer 渲染器用于在 3D 场景中渲染纯…...

centos7 yum install 失败,mirrorlist.centos.org连接不上

由于centos7停止支持,导致mirrorlist.centos.orgdns解析都是失效啦,yum命令没法安装程序. 换一个镜像源就好 sudo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/…...

BGP协议路由黑洞

一、实验环境 1、分公司与运营商AS自治系统内运行IGP路由协议OSPF、RIP或静态路由&#xff0c;AS自治系统内通过IBGP路由协议建立BGP邻居关系。 2、公司AS自治系统与运营商AS自治系统间运行EBGP路由协议。 3、通过loopback建立IBGP与EBGP邻居关系&#xff0c;发挥loopback建立…...

学习ASP.NET Core的身份认证(基于Session的身份认证1)

ASP.NET Core使用Session也可以实现身份认证&#xff0c;关于Session的介绍请见参考文献5。基于Session的身份认证大致原理就是用户验证成功后将用户信息保存到Session中&#xff0c;然后在其它控制器中从Session中获取用户信息&#xff0c;用户退出时清空Session数据。百度基于…...

《Docker Registry(镜像仓库)详解》

一、引言 在容器化技术日益普及的今天&#xff0c;Docker 已成为众多开发者和企业的首选工具。而 Docker Registry&#xff08;镜像仓库&#xff09;作为 Docker 生态系统中的重要组成部分&#xff0c;负责存储和分发 Docker 镜像。本文将深入探讨 Docker Registry 的概念、功能…...

Mybatis

1 什么是MyBatis MyBatis是一个优秀的持久层框架&#xff0c;它对JDBC操作数据库的过程进行封装&#xff0c;使开发者只需要关注 SQL 本身&#xff0c;而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、 结果集检索等JDBC繁杂的过程代码 。…...

uniapp学习(010-3 实现H5和安卓打包上线)

零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战&#xff0c;开发打包微信小程序、抖音小程序、H5、安卓APP客户端等 总时长 23:40:00 共116P 此文章包含第114p-116p的内容 文章目录 H5配置文件设置开始打包上传代码 安卓设置模拟器启动设置基础配置设置图标启动界面…...