Android ART知多少?

Android 虚拟机 ART(Android Runtime)是 Android 平台上的应用程序运行时环境,用于执行应用程序的字节码。ART 自 Android 5.0(Lollipop)开始取代了 Dalvik,成为 Android 的默认运行时环境。本文将从以下几个方面详细系统地介绍 ART,并结合部分源码来探讨其实现原理:

  1. ART 简介
  2. ART 与 Dalvik 的对比
  3. ART 的架构与核心模块
  4. 关键技术
    • Ahead-of-Time 编译 (AOT)
    • Just-In-Time 编译 (JIT)
    • 垃圾回收 (GC)
    • 内存管理与优化
  5. 源码剖析
  6. 性能优化的设计理念
  7. 总结

1. ART 简介

ART 是 Android 平台上的一种高效、稳定的运行时,专为移动设备优化。与 Dalvik 的解释执行不同,ART 结合了提前编译和即时编译,显著提升了应用性能和响应速度,同时降低了内存消耗。

主要特点:

  • 高性能:通过 AOT 和 JIT 提高应用运行效率。
  • 优化内存使用:改进 GC 算法,减少暂停时间。
  • 改进调试工具:支持更强大的调试和分析功能,如 TraceView 和 HPROF。
  • 兼容性强:支持运行旧的 Dalvik 字节码。

2. ART 与 Dalvik 的对比

特性ARTDalvik
编译模式AOT + JIT解释执行 + JIT
初次启动时间较长较短
应用运行性能中等
内存消耗较低较高
垃圾回收并发、低暂停的 GC停止-复制的 GC
支持工具TraceView、Perfetto 等基本调试工具

3. ART 的架构与核心模块

ART 的架构分为以下几个核心部分:

  • ClassLoader: 负责加载字节码。
  • Compiler (AOT/JIT): 提供提前和即时编译功能。
  • Garbage Collector (GC): 负责内存分配与回收。
  • Runtime: 提供运行时环境,管理线程、类、方法调用等。
  • Debugger 和 Profiler: 提供调试和性能分析工具。
    下面是架构图示意:

在这里插入图片描述

4. 关键技术

4.1 Ahead-of-Time 编译 (AOT)

Android Runtime (ART) 的 Ahead-of-Time (AOT) 编译 是一种在应用安装时,将字节码(Bytecode)直接编译为机器码(Native Code)的技术,从而提升应用运行时的性能。下面详细说明:

背景与原理
  1. Dalvik VM 的问题在 Android ART 之前,Android 使用的是 Dalvik 虚拟机,它主要依赖 Just-in-Time (JIT) 编译技术。在应用运行时,字节码被即时编译为机器码,尽管灵活性较高,但存在以下问题:
  • 启动速度慢:每次启动应用时,字节码需要重新编译。
  • 内存占用高:需要维护额外的 JIT 缓存。
  • 性能不稳定:即时编译会增加 CPU 负载,影响用户体验。
  1. ART 的改进:引入 AOT 编译ART 使用 AOT 技术,在应用安装时直接编译字节码为机器码并保存。应用运行时不需要即时编译,直接执行机器码,大大提升了性能。

工作原理

AOT 编译发生在应用安装过程中,主要步骤包括:

  1. 字节码加载从应用的 .dex 文件(包含应用代码的 Dalvik Executable 格式)加载字节码。
  2. 静态编译使用编译器(如 dex2oat)将字节码转换为目标设备的机器码。
  3. 生成 OAT 文件编译后的机器码保存在 OAT 文件中(Optimized Android Runtime 文件),这些文件通常存储在设备的 /data/dalvik-cache 路径下。
  4. 优化与校验
  • ART 在编译过程中会根据设备的 CPU 架构(如 ARM 或 x86)生成优化的机器码。
  • 还会执行验证(Verification),确保编译后的代码不会造成崩溃或安全问题。

优点

  1. 启动更快由于机器码已经编译好,应用启动时无需等待即时编译。
  2. 性能更高
  • 减少运行时的 JIT 编译负担,提升应用流畅性。
  • 更高效的内存使用,因为无需维护 JIT 缓存。
  1. 节能省电运行时的 CPU 开销减少,有助于延长电池续航。

缺点

  1. 安装时间更长 AOT 编译会显著延长应用安装时间,因为需要完成编译和优化过程。
  2. 存储空间占用大编译后的 OAT 文件会占用额外的存储空间。
  3. 灵活性降低动态语言特性(如反射)和运行时修改代码的能力会受到一定限制。

ART 的 AOT 与 JIT 的结合

在 Android 7.0(Nougat)及之后的版本中,ART 引入了 混合编译模式,将 AOT 与 JIT 优势结合:

  • 应用安装时只进行部分 AOT 编译(主要是核心代码)。
  • 运行时,使用 JIT 编译未优化的代码片段,同时记录 JIT 编译结果。
  • 应用闲置时,通过后台编译(Profile-Guided Optimization, PGO),将热点代码进一步转为 AOT 编译,提高性能。

代码示例与工具

  1. dex2oat 工具
    在 Android 系统中,dex2oat 是主要的 AOT 编译工具。你可以使用以下命令查看相关信息:
dex2oat --help
  1. 检查 AOT 文件
    运行设备上的命令,查看已生成的 OAT 文件:
ls /data/dalvik-cache/
  1. 关键函数 art/compiler
bool CompilerDriver::CompileAll() {// 遍历所有的类和方法for (Class c : classes) {for (Method m : c.GetMethods()) {CompileMethod(m);}}return true;
}

总结

ART 的 AOT 编译通过将字节码提前编译为机器码,显著提升了 Android 应用的启动速度和运行性能。尽管有安装时间较长、存储占用等问题,但通过与 JIT 的结合,ART 在后续版本中进一步优化了运行效率和用户体验,是 Android 性能优化的里程碑技术。

在这里插入图片描述

4.2 Just-In-Time 编译 (JIT)

Android Runtime (ART) 的 Just-In-Time (JIT) 编译 是在应用运行时动态编译字节码为机器码的技术,与 Ahead-of-Time (AOT) 编译互为补充,用于提升运行效率并减少应用安装时间。以下是 JIT 编译的详细介绍。

JIT 编译的背景

  1. Dalvik VM 的传统 JIT在 ART 之前,Android 使用的是 Dalvik VM,其核心编译方式就是 JIT。JIT 的特点是按需即时编译,虽然减少了安装时的编译负担,但运行时性能受限,具体表现为:
  • 每次运行时都需要重新编译。
  • 占用额外的 CPU 和内存资源,导致运行时性能波动。
  1. ART 的早期缺陷:全量 AOT 编译在早期 ART(Android 5.0 和 6.0)中,全量 AOT 编译优化了运行时性能,但增加了应用安装时间,且存储占用较高。为平衡性能与灵活性,Android 在 7.0(Nougat)引入了 JIT + AOT 混合模式

JIT 编译的工作原理

ART 中的 JIT 编译在运行时按需触发,以下是其主要工作流程:

  1. 字节码解释执行
  • 应用启动时,ART 会使用解释器逐条执行字节码,快速响应用户请求。
  • 如果某些代码片段(如循环或常用方法)被多次调用,ART 会将其标记为热点代码。
  1. 热点代码的动态编译
  • 当热点代码的执行次数超过一定阈值时,JIT 编译器会将其即时编译为机器码。
  • 编译后的机器码保存在内存中,并直接执行,提高运行效率。
  1. Profile 文件记录
  • 在应用运行过程中,ART 会将热点代码的信息记录到 Profile 文件中。
  • 这些 Profile 数据可用于后续优化,如后台编译(Profile-Guided Optimization,PGO)。
  1. 后台优化与 AOT 的结合
  • 应用空闲时,ART 使用 JIT 记录的 Profile 数据进行增量 AOT 编译,将热点代码进一步优化为高效的机器码。

JIT 的优点

  1. 灵活性高
  • 仅对频繁使用的代码进行编译,减少了不必要的编译开销。
  • 支持动态语言特性(如反射)和运行时动态加载。
  1. 安装时间短
  • 应用安装时无需进行全量 AOT 编译,安装速度更快。
  1. 优化运行性能
  • 动态编译热点代码,提升执行效率。
  • 配合 Profile 数据进行长期优化。

JIT 的缺点

  1. 启动速度相对慢
  • 初次执行代码时,仍需解释执行,直到热点代码触发编译。
  1. 内存占用高
  • 编译后的机器码保存在内存中,占用更多 RAM。
  1. 性能波动
  • 编译过程需要消耗 CPU 资源,在高负载情况下可能影响用户体验。

JIT + AOT 的混合模式

Android 7.0(Nougat)及之后版本中,ART 实现了 JIT 与 AOT 的混合编译模式,以兼顾运行效率和灵活性:

  1. 运行时使用 JIT 编译
  • 应用初次运行时,通过 JIT 编译热点代码,快速优化性能。
  1. 后台优化 AOT 编译
  • 应用空闲时,利用 Profile 数据增量编译机器码,生成优化的 OAT 文件,供后续运行使用。
  1. 适应设备环境
  • JIT 和 AOT 编译结果均针对设备的 CPU 架构优化,提供更好的运行效率。

示例与工具

  1. Profile 文件查看Profile 文件通常存储在以下路径:
/data/data//code_cache/profile/
  1. ART 的优化工具使用 profman 工具分析 Profile 数据:
profman --dump-profile-info --profile-file=
  1. 实时调试 JIT 编译开启 ART 的 JIT 调试日志:
setprop dalvik.vm.extra-opts -verbose:jit
  1. JIT 编译示例代码 art/runtime/jit
void Jit::CompileMethod(Method* method) {if (IsHotMethod(method)) {CompileToMachineCode(method);}
}

总结

ART 的 JIT 编译通过动态编译热点代码,提供了高效灵活的性能优化方式,与 AOT 编译相辅相成。在应用安装、运行和优化的不同阶段,JIT 编译减少了安装时间,提升了运行性能,同时为后台 AOT 优化提供了数据支持。这种混合编译模式在 Android 系统中实现了性能与灵活性的良好平衡。

在这里插入图片描述

4.3 垃圾回收 (GC)

Android Runtime (ART) 的垃圾回收(Garbage Collection, GC)机制负责自动管理应用的内存,释放不再使用的对象所占用的空间,从而避免内存泄漏和提升性能。ART 的垃圾回收相较于 Dalvik 虚拟机有显著改进,以下是详细介绍:

ART 垃圾回收的基本原理

  1. 对象分配与生命周期
  • ART 管理的内存堆分为不同区域(如年轻代和老年代)。
  • 应用运行时在堆上分配内存,对象的生命周期决定了它被回收的时机。
  1. 垃圾回收触发条件垃圾回收的触发通常基于以下条件:
  • 堆内存不足:新对象分配时发现堆已满。
  • 手动触发:某些 API(如 System.gc())可能提示进行回收。
  • 内存优化:系统主动回收内存以提升性能。
  1. 标记-清除算法ART 的 GC 使用 标记-清除(Mark-and-Sweep) 算法,分为以下步骤:
  • 标记阶段:找到所有活跃的对象(可达的对象)。
  • 清除阶段:释放未标记(不可达)的对象所占的内存。
    在这里插入图片描述

ART 垃圾回收的特点

  1. 并发垃圾回收ART 使用并发 GC,将垃圾回收的部分任务分摊到多个线程中,从而减少对主线程的影响,提高应用的流畅性。
  2. 低延迟设计
  • ART 针对交互式应用进行了优化,尽可能缩短 GC 的暂停时间(GC Pause Time)。
  • 在用户操作频繁的时刻(如滑动列表),ART 尽量避免大规模的回收操作。
  1. 分代回收ART 使用分代式垃圾回收策略,将堆分为以下几部分:
  • 年轻代(Young Generation):存放生命周期短的对象,回收频率高。
  • 老年代(Old Generation):存放生命周期长的对象,回收频率低。
  1. 增量回收ART 的 GC 还支持增量回收(Incremental GC),将一次性的大量回收操作分解为小批量的任务,降低应用响应的卡顿。

ART 的垃圾回收类型

ART 提供多种垃圾回收类型,根据需求自动切换:

  1. Partial GC(部分回收)
  • 仅回收年轻代对象。
  • 触发快,暂停时间短。
  1. Full GC(完全回收)
  • 回收整个堆,包括年轻代和老年代。
  • 通常在堆内存不足时触发,暂停时间较长。
  1. Concurrent GC(并发回收)
  • 在后台线程执行垃圾回收。
  • 减少对主线程的影响,提高性能。
  1. Compacting GC(压缩回收)
  • 重新整理内存堆,将分散的内存块合并为连续的内存。
  • 提高后续对象分配的效率,避免内存碎片问题。
  1. Sticky GC(粘性回收)
  • 仅清理应用运行期间新分配的短生命周期对象。
  • 触发快,适用于频繁分配对象的场景(如动画或 UI 渲染)。

ART GC 的优化

  1. 避免频繁触发 GC
  • 频繁分配短生命周期对象可能导致频繁的垃圾回收,从而影响性能。
  • 优化方法:减少临时对象的创建,尤其是在循环中。
  1. 减小堆内存压力
  • 控制对象大小,避免一次性分配过多大对象(如 Bitmap)。
  • 优化方法:使用 Bitmap.recycle() 主动释放资源。
  1. 监控 GC 行为
  • 通过 Android Studio Profiler 或 adb logcat 查看 GC 日志,了解回收频率和暂停时间:
adb logcat | grep GC
  1. 调整堆大小
  • AndroidManifest.xml 中通过 android:largeHeap 属性申请更大的堆内存,但仅在必要时使用。
  • 示例:
<applicationandroid:largeHeap="true">
</application>

在这里插入图片描述

GC 日志示例

以下是 ART GC 的典型日志:

GC concurrent freed 2048K, 10% free 20480K/22528K, paused 5ms+2ms, total 10ms

日志含义:

  • GC concurrent:并发回收。
  • freed 2048K:释放了 2MB 内存。
  • 10% free:堆剩余 10% 的空闲空间。
  • 20480K/22528K:堆当前使用 20MB,总大小为 22MB。
  • paused 5ms+2ms:主线程暂停时间分别为 5ms 和 2ms。
  • total 10ms:总回收时间为 10ms。

总结

ART 的垃圾回收机制通过分代式设计、并发回收和增量回收等方式,实现了低延迟、高效的内存管理。这种机制在减少内存泄漏、优化性能方面有显著效果,但开发者仍需遵循最佳实践(如减少对象分配和合理使用内存)来配合 GC 的高效运行,从而保证应用的流畅性和稳定性。

在这里插入图片描述

4.4 内存管理与优化

Android Runtime (ART) 的内存模型和优化机制是其高性能运行的核心。相比于早期的 Dalvik 虚拟机,ART 在内存管理和优化方面做出了许多改进,使得应用运行更加高效、流畅且节能。以下是 ART 的内存模型及其优化原理的详细介绍:

ART 的内存模型

ART 的内存模型由以下几个主要部分组成:

1. 堆内存

堆是 ART 中分配对象的主要区域,由以下几个部分组成:

  • 年轻代(Young Generation): 存储生命周期较短的对象。包括 Eden 区和两个 Survivor 区。对象大多在此区域被创建和回收。采用高频率的垃圾回收机制,回收快,暂停时间短。
  • 老年代(Old Generation): 存储生命周期较长的对象(多次在年轻代垃圾回收中幸存)。回收频率低,但占用空间大。通常在 Full GC 时进行回收。

2. 栈内存

  • 每个线程都有自己的独立栈,用于存储局部变量、方法调用信息等。
  • 栈内存生命周期与线程一致,线程结束时栈内存自动释放。

3. 方法区

  • 用于存储类的元信息(如方法、字段等)。
  • 在 ART 中,这部分被称为 Class Metadata,其管理更加高效且占用较少内存。

4. 本地内存(Native Heap)

  • 由 JNI 或底层库分配,与 ART 的堆分开管理。
  • 主要用于直接与操作系统交互的资源(如 Bitmap、OpenGL 等)。

ART 内存管理的关键特性

1. 分代式内存管理

ART 实现了分代式内存管理,针对不同生命周期的对象采用不同的策略:

  • 短生命周期对象(年轻代): 采用高效的复制垃圾回收(Copying GC)算法,快速回收。
  • 长生命周期对象(老年代): 使用标记-清除(Mark-and-Sweep)算法进行回收,减少停顿时间。
  • 粘性垃圾回收(Sticky GC): 仅回收最近分配的短生命周期对象,适用于频繁内存分配的场景。

2. 内存对齐与压缩

ART 优化了内存分配的方式:

  • 对象内存对齐: 保证对象存储在对齐的地址上,提升访问效率。
  • 指针压缩(Pointer Compression): 在 64 位架构下,通过压缩指针(将 64 位指针压缩为 32 位),减少内存占用。

3. 增量分配与回收

  • ART 引入增量内存分配和回收机制,将内存操作分散到多个时刻,降低单次分配或回收的延迟。

4. 垃圾回收优化

  • 并发垃圾回收(Concurrent GC): 在后台线程完成标记和清除工作,减少主线程的阻塞时间。
  • 压缩垃圾回收(Compacting GC): 防止内存碎片,通过整理内存堆空间提升后续分配效率。

ART 内存优化的核心技术

1. 即时与延迟分配

ART 在对象分配时,使用线程本地分配缓冲区(Thread Local Allocation Buffer, TLAB):

  • 分配效率提升: 每个线程独立分配小块内存,减少锁竞争。
  • 减少全局锁冲突: 提高多线程环境下的内存分配效率。

2. 内存释放与复用

ART 优化了内存释放的机制:

  • 回收后的内存块会直接进入内存池,供后续对象分配复用,减少操作系统层的内存申请。

3. 代码与数据共享

  • Dex 文件优化: ART 将 .dex 文件编译为更高效的 OAT 文件,减少内存消耗。
  • 字符串池: ART 实现了全局字符串池,共享重复字符串以减少内存占用。

4. 多用户优化

  • ART 针对 Android 多用户模式优化了资源共享机制,例如系统类的元信息仅加载一次并共享。

ART 内存模型优化的效果

1. 提高运行性能

  • 减少垃圾回收引起的停顿时间,提升应用响应速度。
  • 增强内存分配效率,特别是高频次对象分配场景(如 UI 渲染)。

2. 降低内存占用

  • 通过指针压缩、字符串池等技术,减少应用的内存足迹。
  • 内存复用机制避免了频繁的内存分配和回收。

3. 提升设备续航

  • 更高效的内存管理降低了 CPU 和内存的使用率,从而减少电池消耗。

开发者优化内存的最佳实践

1. 避免内存泄漏

  • Context 管理: 避免长生命周期对象持有短生命周期的 Context。
  • 工具检测: 使用 Android Studio Profiler 或 LeakCanary 检测内存泄漏。

2. 减少临时对象分配

  • 避免在循环中频繁分配短生命周期对象。
  • 使用对象池(Object Pool)复用高频创建的对象。

3. 优化大对象使用

  • 对于 Bitmap 等大对象,使用 Bitmap.recycle() 主动释放内存。
  • 尽量使用合适的压缩格式(如 WebP)降低图片大小。

4. 使用 Android 平台特性

  • 配置适当的 android:largeHeap 仅在必要时使用。
  • 利用 Profile-Guided Optimization (PGO) 提升运行时效率。

总结

ART 的内存模型通过分代管理、并发回收、压缩优化等技术,提供了高效的内存分配和回收机制,减少了内存泄漏和性能瓶颈。此外,ART 针对特定设备和应用场景的优化(如指针压缩和 TLAB)显著提升了应用的运行效率。开发者需结合 ART 的内存特性,配合最佳实践,确保应用在各种设备上的内存使用和性能表现达到最佳状态。

在这里插入图片描述

5. 源码剖析

5.1 ART 初始化

ART 在启动时初始化环境,包括类加载器、GC 和编译器等。

源码路径:

  • art/runtime/runtime.cc
    关键函数:
void Runtime::Init() {// 初始化 GCInitGC();// 初始化编译器InitCompiler();// 加载基本类LoadBaseClasses();
}
5.2 方法执行

ART 通过解释器或编译器执行方法。

源码路径:

  • art/runtime/interpreter/interpreter.cc
    核心代码:
void Interpreter::ExecuteMethod(Thread* thread, Method* method) {if (method-&gt;IsCompiled()) {ExecuteCompiledCode(thread, method);} else {ExecuteDexCode(thread, method);}
}

6. 性能优化的设计理念

  1. 冷热分离:通过 JIT 编译和 Profiling 分析,将热方法进行动态优化。
  2. 减少停顿时间:通过并发 GC 减少应用的响应延迟。
  3. 内存优化:利用 TLAB 和大型对象空间优化内存分配。

7. 总结

ART 作为 Android 平台的核心运行时环境,大幅度提升了应用性能和用户体验。它的 AOT 和 JIT 编译器、并发垃圾回收和先进的内存管理为 Android 应用的高效运行提供了强有力的保障。

通过分析 ART 源码,我们能够深入理解其设计理念和实现细节,为开发高性能 Android 应用打下坚实基础。如果您有更多深入学习的需求,可以进一步探索 ART 的调试工具和优化方法。

参考

Memory Management in Android
Android CPU, Compilers, D8 & R8

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/472279.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

黑马嵌入式开发入门模电基础学习笔记

学习视频: 黑马程序员嵌入式开发入门模电&#xff08;模拟电路&#xff09;基础 文章目录 背景介绍电流电压组件仿真三极管ne555PCBEDA案例&#xff1a;非接触式电笔案例&#xff1a;电子琴 背景介绍 电流 电压 组件 仿真 三极管 mos管 ne555 PCB EDA 案例&#xff1a;非接触…

Ubuntu 18 EDK2 环境编译

视频&#xff1a;在全新的Ubuntu上从零搭建UEFI的EDK2开发环境 开始&#xff1a;git clone https://github.com/tianocore/edk2.git 开始编译BaseTools前先更新一下子模块&#xff1a;git submodule update --init &#xff0c;然后&#xff1a;make -C BaseTools/ 问题1&a…

第9章 DIV+CSS布局

9.1 DIVCSS概述 DIVCSS是Web设计标准&#xff0c;它是一种网页的布局方法。与传统中通过表格&#xff08;table)布局定位的方式不同&#xff0c;它可以实现网页页面内容与表现相分离。DIV组成了网页的格局&#xff0c;CSS则装饰了格局&#xff0c;比如建一栋房子&#xff0c;…

QT QLineEdit失去焦点事件问题与解决

本文介绍如何获得QLineEdit的失去焦点事件和获得焦点的输入框也会触发失去焦点事件的问题&#xff01; 目录 一、QLineEdit获得失去焦点事件 1.自定义类继承自QLineEdit 2.重写 focusOutEvent 3.使用 二、失去焦点事件问题 1.问题描述 2.问题解决 三、源码分享 lineed…

微信小程序navigateTo:fail webview count limit exceed

theme: nico 你们好&#xff0c;我是金金金。 场景 uniapp编写微信小程序&#xff0c;使用uni.navigateTo跳转的过程中报错如下&#xff1a; 报错意思也非常明显了&#xff1a;errMsg":"navigateTo:fail webview 数量超出限制 排查 排查之前我先贴一下代码 代码非…

HarmonyOS ArkTs 解决流式传输编码问题

工作日志 日期&#xff1a;2024-11-15 标题&#xff1a;HarmonyOS ArkTs 解决流式传输编码问题 问题描述 问题&#xff1a;在处理流式数据的 HTTP 请求时&#xff0c;服务器返回的数据存在编码问题&#xff0c;导致数据无法正确地解码为字符串。部分数据在解码后出现了乱码…

Android Settings 单元测试 | 如何运行单元测试?

背景 在Android Settings 单元测试 | Telephony Network 模块 APN 案例中粗略介绍了单元测试逻辑内容&#xff0c;但是在独立APK里面如何将单元测试跑起来还是有疑问&#xff0c;因为APP不能直接install&#xff0c;无法借助Android Studio直接Run&#xff0c;在安装的一步会报…

flutter字体大小切换案例 小字体,标准字体,大字体,超大字体案例

flutter字体大小切换案例 小字体&#xff0c;标准字体&#xff0c;大字体&#xff0c;超大字体案例 Android iOS设备带有选择记录 我的flutter项目版本 environment: sdk: ‘>3.4.4 <4.0.0’ 图片案例 pubspec.yaml 添加依赖 # 屏幕尺寸适配 https://github.com/OpenF…

编译原理(手绘)

大家好&#xff0c;今天给大家分享一下我自己对c语言编译链接的一点见解&#xff08;本人是学生&#xff0c;有记笔记的习惯&#xff09;&#xff0c;那么今天就给大家分享我的笔记。 以上只是我本人的一些见解&#xff0c;并非绝对&#xff0c;欢迎大家一起交流。 那么今天分…

跳房子(弱化版)

题目描述 跳房子&#xff0c;也叫跳飞机&#xff0c;是一种世界性的儿童游戏&#xff0c;也是中国民间传统的体育游戏之一。 跳房子的游戏规则如下&#xff1a; 在地面上确定一个起点&#xff0c;然后在起点右侧画 n 个格子&#xff0c;这些格子都在同一条直线上。每个格子内…

初识Linux · 共享内存

目录 理解共享内存 Shared memmory code 理解共享内存 前文介绍的管道方式的通信&#xff0c;本文介绍的是进程通信的另外一种方式&#xff0c;即共享内存。但是这种通信方式的特点是只能本地通信&#xff0c;并且不像管道那样有保护机制&#xff0c;这里是没有的。 我们通…

机器学习day5-随机森林和线性代数1

十 集成学习方法之随机森林 集成学习的基本思想就是将多个分类器组合&#xff0c;从而实现一个预测效果更好的集成分类器。大致可以分为&#xff1a;Bagging&#xff0c;Boosting 和 Stacking 三大类型。 &#xff08;1&#xff09;每次有放回地从训练集中取出 n 个训练样本&…

Essential Cell Biology--Fifth Edition--Chapter one (6)

1.1.4.4 Internal Membranes Create Intracellular Compartments with Different Functions [细胞膜形成具有不同功能的细胞内隔室] 细胞核、线粒体和叶绿体并不是真核细胞中唯一的膜包围细胞器。细胞质中含有大量的[ a profusion of]其他细胞器&#xff0c;这些细胞器被单层膜…

基于VUE实现语音通话:边录边转发送语言消息、 播放pcm 音频

文章目录 引言I 音频协议音频格式:音频协议:II 实现协议创建ws对象初始化边录边转发送语言消息 setupPCM按下通话按钮时开始讲话,松开后停止讲话播放pcm 音频III 第三库recorderplayer调试引言 需求:电台通讯网(电台远程遥控软件-超短波)该系统通过网络、超短波终端等无线…

政务数据治理专栏开搞!

写在前面 忙忙碌碌干了一年政务数据治理的工作&#xff0c;从法人数据到自然人&#xff0c;从交通到地理信息等等&#xff0c;突发想法开一个专栏讲一讲政务数据遇到的问题&#xff0c;以及治理的成效&#xff0c;或许有朋友爱看。 政务数据&#xff0c;又称之为政务数据资源&a…

CondaError: Run ‘conda init‘ before ‘conda activate‘解决办法

已经执行了conda init&#xff0c;但是还是会报错CondaError: Run ‘conda init’ before ‘conda activate’ 原因&#xff1a;权限不够 解决办法&#xff1a;以管理员身份运行cmd&#xff0c;然后进入要操作的文件夹下&#xff0c;重新执行 conda init 和 conda activate 就可…

【全面系统性介绍】虚拟机VM中CentOS 7 安装和网络配置指南

一、CentOS 7下载源 华为源&#xff1a;https://mirrors.huaweicloud.com/centos/7/isos/x86_64/ 阿里云源&#xff1a;centos-vault-7.9.2009-isos-x86_64安装包下载_开源镜像站-阿里云 百度网盘源&#xff1a;https://pan.baidu.com/s/1MjFPWS2P2pIRMLA2ioDlVg?pwdfudi &…

软考教材重点内容 信息安全工程师 第 4 章 网络安全体系与网络安全模型

4,1 网络安全体系的主要特征: (1)整体性。网络安全体系从全局、长远的角度实现安全保障&#xff0c;网络安全单元按照一定的规则&#xff0c;相互依赖、相互约束、相互作用而形成人机物一体化的网络安全保护方式。 (2)协同性。网络安全体系依赖于多种安全机制&#xff0c;通过各…

让空间计算触手可及,VR手套何以点石成金?

引言 如何让一位母亲与她去世的小女儿“重逢”&#xff1f;韩国MBC电视台《I Met You》节目实现了一个“不可能”心愿。 在空旷的绿幕中&#xff0c;母亲Jang Ji-sung透过VR头显&#xff0c;看到了三年前因白血病去世的女儿Nayeon。当她伸出双手&#xff0c;居然能摸到女儿的…

[Admin] Dashboard Filter for Mix Report Types

Background RevOps team has built a dashboard for sales team to track team members’ performance, but they’re blocked by how to provide a manager view based on sales’ hierarchy. Therefore, they seek for dev team’s help to clear their blocker. From foll…