Swift与iOS内存管理机制深度剖析
前言
内存管理是每一位 iOS 开发者都绕不开的话题。虽然 Swift 的 ARC(自动引用计数)极大简化了开发者的工作,但只有深入理解其底层实现,才能写出高效、健壮的代码,避免各种隐蔽的内存问题。本文将从底层原理出发,系统梳理 Swift 与 iOS 的内存管理机制,结合实战经验,分享常见问题与优化建议。
一、ARC 的底层实现原理
1.1 ARC 的本质与设计目标
ARC(Automatic Reference Counting,自动引用计数)并非传统意义上的垃圾回收器(如 Java 的 GC),而是一种编译器驱动的内存管理机制。其核心设计目标包括:
- 自动管理对象生命周期,有效防止内存泄漏和野指针问题;
- 高性能,最大限度减少运行时的性能损耗;
- 开发者友好,让开发者专注于业务逻辑,无需手动管理内存。
1.2 编译器插桩机制
ARC 的实现依赖于编译器插桩:在源码编译阶段,编译器会自动在合适的位置插入 retain、release、autorelease 等内存管理指令。开发者无需手动调用这些方法,编译器会根据变量作用域、闭包捕获等场景自动生成相应的代码。
例如,以下 Swift 代码:
func foo() {let obj = MyClass()obj.doSomething()
}
Swift 编译器会在需要时插入 swift_retain 和 swift_release 调用,编译后,等价于如下伪代码:
let obj = swift_alloc(MyClass)
swift_retain(obj)
obj.doSomething()
swift_release(obj)
开发者无需手动管理这些操作,编译器会根据变量作用域、闭包捕获等场景自动插入合适的指令。
1.3 retain/release 的底层原理
每当你增加或减少一个对象的强引用时,Swift 底层会自动用 swift_retain 或 swift_release 这类函数。
- retain:将对象的引用计数加一。
- release:将对象的引用计数减一。如果计数减到零,系统会自动调用对象的析构方法(deinit),并释放其占用的内存。
在多线程环境下,可能会有多个线程同时对同一个对象进行 retain 或 release 操作。为了避免数据竞争和计数错误,Swift 在底层实现中采用了原子操作(atomic operation),例如 C++11 的 std::atomic。这样可以确保每一次引用计数的增加或减少都是安全且不可分割的,避免出现“加错”或“减错”的情况,从而保证了 ARC 在多线程下的正确性和稳定性。
1.4 对象销毁的完整流程
- 当引用计数减为零:当最后一个强引用消失,release 操作使引用计数变为 0。
- 调用析构方法:Swift 自动调用对象的 deinit 方法(Objective-C 为 dealloc),用于资源清理、通知等。
- 释放成员变量:对象的所有成员变量(包括强引用的其他对象)会被依次 release,递归触发它们的引用计数变化。
- 回收内存:对象的内存块被系统回收,彻底释放。
1.5 ARC 的作用范围
- ARC 主要作用于类(class)类型的实例。只有引用类型(如 class、NSObject 及其子类)才有引用计数,受 ARC 管理。
- 结构体(struct)和枚举(enum)为值类型,生命周期由作用域自动管理,不参与 ARC。
1.6 引用计数的类型
ARC 支持多种引用类型,不同类型对引用计数的影响不同:
- 强引用(strong):默认引用类型,持有对象时引用计数加一,保证对象在引用期间不会被释放。
- 弱引用(weak):不增加引用计数,目标对象释放后自动置为 nil,常用于避免循环引用。
- 无主引用(unowned):同样不增加引用计数,但目标对象释放后不会自动置为 nil,如果访问已释放对象会导致程序崩溃。适用于生命周期绑定但不会为 nil 的场景。
二、Swift 对象的内存布局与引用计数存储
在理解 ARC 的底层实现时,首先要搞清楚 Swift 类对象在内存中的真实样子。其实,每个 Swift 类对象在内存中都包含了类型信息、引用计数和实际的数据。下面我们用通俗的方式来拆解。
2.1 Swift 对象的内存结构是什么样的?
你可以把 Swift 的类对象想象成一排盒子,每个盒子里装着不同的信息。
假设你有这样一个类:
class Dog {var age: Int32 // 4字节var weight: Double // 8字节
}
当你写 let dog = Dog() 时,系统会在内存里为这个对象分配一块连续的空间。
这块空间的内容和顺序大致如下:
| 盒子1 | 盒子2 | 盒子3 | 盒子4 | 盒子5 |
|---------------|-----------------|---------|---------|---------|
| isa指针 | 引用计数/标志位 | padding | age属性 | weight属性 |
每个盒子装的是什么?
- isa指针:告诉系统“我是什么类型”,比如“我是Dog类”。用于类型识别、方法分发等。
- 引用计数/标志位:记录有多少人在用这个对象(ARC用来决定何时释放内存),有时还包含一些标志位(如是否用旁表、是否已释放等)。
- padding:有时候为了让后面的数据对齐,系统会加点“空盒子”。
- age属性:你定义的 age 变量。
- weight属性:你定义的 weight 变量。
2.2 伪代码结构
struct DogObject {uintptr_t isa; // 8字节,类型信息uint32_t refCount; // 4字节,引用计数uint32_t padding; // 4字节,填充int32_t age; // 4字节,age属性double weight; // 8字节,weight属性
};
2.2.1 为什么要有 padding(填充)?
因为有些数据类型(比如 Double)要求在内存中“对齐”,这样 CPU 读取更快。
如果前面不是8的倍数,就会加点“空盒子”让后面的数据排整齐。
2.2.2 假设内存地址从低到高排列:
| isa | refCount | padding | age | weight |
- isa(8字节)
- refCount(4字节)
- padding(4字节,为了让 weight 对齐)
- age(4字节)
- weight(8字节)
2.3 引用计数的内容和格式
引用计数字段不仅仅是一个简单的数字,通常还包含一些标志位,比如:
- 是否已经被释放
- 是否正在使用旁表
- 是否是无主引用(unowned)
这些信息一般通过位运算存储在同一个字段里。
2.4 引用计数的存储方式
Swift 的引用计数有两种存储方式:
2.4.1. 内联计数(Inline Refcount)
大多数情况下,Swift 对象的引用计数直接存储在对象头部(即结构体中的 refCount 字段)。这种方式被称为内联计数(Inline Refcount)。
2.4.1.1 为什么要这样设计?
- 高效访问:引用计数和对象本身在同一块内存区域,CPU 读取和修改都非常快,无需额外寻址。
- 空间节省:绝大多数对象的引用计数都不会很大,直接用对象头部的几个字节就能满足需求,避免了为每个对象单独分配计数空间。
- 局部性原理:对象和其引用计数在内存上相邻,提升了缓存命中率,进一步加快了访问速度。
2.4.2. 旁表(Side Table)
在 Swift 的 ARC 内存管理体系中,Side Table(旁表)是一种用于辅助管理对象引用计数和其他元数据的全局数据结构。它的本质是一个哈希表。key 是对象的内存地址,value 是该对象的引用计数及相关信息
2.4.2.1 为什么需要 Side Table?
大多数情况下,对象的引用计数直接存储在对象头部(内联存储),这样效率最高。但有些特殊场景下,内联存储就不够用了:
- 引用计数溢出:比如一个对象被成千上万个地方强引用,内联计数位数不够用。
- 需要存储额外信息:如弱引用(weak)、无主引用(unowned)等元数据,或者调试信息。
- 对象参与复杂的内存管理策略:如与 Objective-C 混用时的特殊处理。
这时,Swift 会自动将该对象的引用计数和相关信息迁移到 Side Table 中。
2.4.2.2 Side Table 的结构和原理
Side Table 可以理解为一个全局的哈希表,结构大致如下(伪代码):
struct SideTableEntry {int strongRefCount; // 强引用计数int unownedRefCount; // 无主引用计数// 可能还有其他元数据
}std::unordered_map<void*, SideTableEntry> sideTable;
- 查找:通过对象的内存地址查找对应的 Side Table Entry。
- 操作:对 Entry 里的计数进行原子加减,保证线程安全。
2.4.2.3 Side Table 的性能影响
- 绝大多数对象不会用到 Side Table,只有极少数“特殊对象”才会迁移到旁表。
- 这样设计的好处是:常规对象的引用计数操作非常快,只有极端情况才会牺牲一点性能,换取更大的灵活性和安全性。
2.4.2.4 Side Table 与弱引用(weak)的关系
- 当你在 Swift 里声明 weak 属性时,系统会为该对象在 Side Table 里登记一份弱引用信息。
- 当对象引用计数为 0、即将销毁时,Side Table 会负责把所有指向它的 weak 指针自动置为 nil,防止野指针。
2.4.2.5 Side Table 的生命周期
- Side Table 的 Entry 会在对象销毁后自动清理,避免内存泄漏。
- 你无需手动管理 Side Table,Swift 运行时会自动处理。
Side Table 是 Swift ARC 内存管理体系中一个“幕后英雄”,它为极端场景下的对象引用计数和弱引用管理提供了强有力的支持。虽然大多数开发者感受不到它的存在,但正是有了 Side Table,Swift 才能兼顾高性能与高灵活性,安全地管理各种复杂对象的生命周期。
三、Swift 与 Objective-C ARC 的底层差异
在 iOS 开发中,Swift 和 Objective-C 都采用了 ARC(自动引用计数)来管理内存,但它们在底层实现上有一些重要的区别。理解这些差异,有助于我们在混合开发或排查内存问题时更加得心应手。
3.1 引用计数的存储方式
- Objective-C 的对象引用计数不会存储在对象头部。每个 OC 对象的头部只有一个 isa 指针(指向类的元数据)。引用计数信息存储在一个全局的 Side Table(旁表)中。每次 retain/release 操作,系统会通过对象地址查找 Side Table 并更新计数。这种方式实现简单,但频繁查表会带来一定性能开销。
- Swift 对象的引用计数更为高效。大多数情况下,Swift 会把引用计数直接存储在对象头部的某些比特位中(Inline Refcount)。只有在引用计数非常大或需要特殊管理时,才会像 Objective-C 一样转移到旁表。这种设计减少了查表次数,提高了性能。
3.2 对象元数据结构
-
在 Objective-C 中,每个对象的内存布局非常简单。对象的头部第一个字段就是一个 isa 指针。这个指针指向该对象所属类的元数据(class object),元数据中包含了方法列表、属性列表等信息。通过 isa 指针,Objective-C 运行时可以实现方法查找、类型判断等功能。
- Swift 的类对象同样在头部包含一个指向元数据的指针,这个指针在 Swift 中通常被称为metadata pointer,有时也叫 isa。这个指针同样位于对象内存的起始位置,即对象的第一个字段。该指针指向 Swift 的类型元数据(metadata),元数据结构比 Objective-C 更复杂,包含类型信息、协议、方法表等。这样可以支持更多高级特性,比如泛型和协议扩展。
3.3 引用类型的差异
- Objective-C 只有强引用(strong)和弱引用(weak),没有无主引用(unowned)的概念。弱引用在对象释放后会自动置为 nil,防止野指针。
- Swift 除了 strong 和 weak,还引入了 unowned(无主引用)。unowned 引用不会增加引用计数,但对象释放后不会自动置为 nil。如果访问已释放的对象会导致崩溃。unowned 适用于生命周期绑定但不会为 nil 的场景,比如 delegate。
3.4 ARC 的桥接与兼容
Swift 和 Objective-C 的对象可以互相引用,ARC 机制能够自动适配。例如,Swift 的类继承自 NSObject 时,ARC 会自动桥接引用计数,保证内存安全。开发者在混合开发时无需手动干预,大多数情况下可以无缝协作。
3.5 小结
Swift 和 Objective-C 的 ARC 虽然目标一致,但底层实现各有优化。Swift 更注重性能和类型安全,采用了更高效的引用计数存储方式,并引入了 unowned 引用类型。了解这些差异,有助于我们写出更高效、更安全的代码,尤其是在 Swift 与 Objective-C 混合开发时。
四、内存管理中的底层陷阱与调试技巧
4.1 循环引用的本质与解决方法
在 ARC 机制下,循环引用(Retain Cycle)是最常见的内存泄漏问题。它的本质是:两个或多个对象之间互相持有强引用,导致它们的引用计数永远不会变为 0,内存无法被释放。
举个例子:
class Person {var pet: Pet?
}class Pet {var owner: Person?
}
如果 Person 和 Pet 互相强引用对方,即使它们都不再被外部引用,也不会被释放,造成内存泄漏。
解决方法:
Swift 提供了两种弱引用方式:
- weak(弱引用):不会增加引用计数,引用对象被释放后自动变为 nil,适合可选类型。
- unowned(无主引用):不会增加引用计数,引用对象被释放后不会变为 nil,适合生命周期一致的非可选类型。
推荐做法:
在需要打破循环引用的地方,将一方声明为 weak 或 unowned,比如:
class Pet {weak var owner: Person?
}
这样就能保证对象在不再被需要时正确释放。
4.2 闭包与 self 的循环引用
Swift 的闭包(Closure)默认会强引用捕获的对象,尤其是 self。如果在类中将闭包作为属性,并在闭包内访问 self,就会形成循环引用。
典型场景:
class MyClass {var closure: (() -> Void)?func setup() {closure = {self.doSomething()}}
}
解决方法:
使用捕获列表,将 self 以 weak 或 unowned 方式捕获:
closure = { [weak self] inself?.doSomething()
}
这样可以有效避免循环引用。
如果对闭包有疑问,可以看我的博客:Swift闭包(Closure)深入解析与底层原理
4.3 AutoreleasePool 的底层机制
虽然 Swift 很少直接用 @autoreleasepool,但在与 Objective-C 代码交互或大量临时对象创建时,AutoreleasePool 依然很重要。
AutoreleasePool 的本质是一个栈结构,存储了“待释放”的对象指针。每当 pool 被销毁或“排空”时,栈中的对象会统一调用 release,从而释放内存。
典型场景:
在 for 循环中大量创建临时对象时,可以手动包裹 @autoreleasepool,及时释放内存,避免内存峰值过高。
for _ in 0..<10000 {autoreleasepool {// 创建大量临时对象}
}
5.4 内存泄漏与僵尸对象的调试
Swift 和 iOS 提供了多种工具帮助我们发现和定位内存问题:
- Xcode Instruments:使用 Leaks、Allocations 工具可以追踪对象的分配、引用计数变化和泄漏点。
- 静态分析:Xcode 的 Analyze 功能可以在编译时发现潜在的内存泄漏。
- NSZombieEnabled:设置环境变量 NSZombieEnabled=YES,可以让已释放的对象变成“僵尸对象”,帮助定位野指针访问问题。
总结
本文系统梳理了 Swift 与 iOS 的内存管理机制,从 ARC 的底层原理、对象内存布局、引用计数存储方式,到 Swift 与 Objective-C ARC 的差异,再到常见内存陷阱与调试技巧,力求让开发者对 iOS 内存管理有更深入、全面的理解。
Swift 的 ARC 通过编译器插桩自动管理对象生命周期,极大简化了开发者的工作,但其底层实现却蕴含诸多细节与优化。例如,Swift 采用内联引用计数与旁表(Side Table)相结合的方式,既保证了性能,又兼顾了灵活性和安全性。与 Objective-C 相比,Swift 在类型安全、引用类型(如 unowned)等方面也做了更多优化。
在实际开发中,循环引用、闭包捕获 self、AutoreleasePool 的使用等,都是内存管理的高频考点。只有理解底层原理,才能在遇到复杂场景时游刃有余,写出高效、健壮的代码。善用 Xcode Instruments、静态分析、NSZombieEnabled 等工具,可以帮助我们及时发现和定位内存问题,提升代码质量。
总之,内存管理是每一位 iOS 开发者的必修课。希望本文能帮助你建立起系统的知识体系,少踩坑,多写优雅高效的 Swift 代码。如果你有更多关于 Swift 内存管理的疑问或经验,欢迎在评论区交流讨论!
如果觉得本文对你有帮助,欢迎点赞、收藏、关注我,后续会持续分享更多 iOS 底层原理与实战经验!
相关文章:
Swift与iOS内存管理机制深度剖析
前言 内存管理是每一位 iOS 开发者都绕不开的话题。虽然 Swift 的 ARC(自动引用计数)极大简化了开发者的工作,但只有深入理解其底层实现,才能写出高效、健壮的代码,避免各种隐蔽的内存问题。本文将从底层原理出发&…...
数据库系统概论(五)关系模型的数据结构及形式化
数据库系统概论(五)关系模型的数据结构及形式化 前言一、关系:从“表格”说起1.1 关系数据模型中的“关系”是什么?1.2 域(Domain):数据的“类型限定”1.3 笛卡尔积(Cartesian Produ…...
Python类和对象四(十三)
魔法方法: 按位运算 按位于运算 只要相同才是1 或运算: 只要某个位是1结果就是1 、 按位非 将结果取反 按位异或: 左移和右移运算符: 右移两位 右移动n位,就是除以2的n次方 左移两位: 左移n位就是乘…...
Go 1.24 中的弱指针包 weak 使用介绍
在 Go 语言中,“弱指针”指的是不会阻止垃圾回收器(GC)回收目标对象的引用。 当一个对象只剩弱指针指向它,而没有任何强引用时,GC 仍会把该对象当作不可达对象并回收;随后,所有指向它的弱指针会…...
毕业项目-基于深度学习的入侵检测系统
选题背景与意义 随着互联网技术的飞速发展,网络在各个领域中的作用日益重要。然而,伴随着技术的进步,网络安全问题也愈加严峻,网络攻击事件频繁发生,给个人、企业乃至国家带来了巨大的经济损失与安全威胁。入侵检测系…...
Github 2025-04-26 Rust开源项目日报Top10
根据Github Trendings的统计,今日(2025-04-26统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10Dart项目1RustDesk: 用Rust编写的开源远程桌面软件 创建周期:1218 天开发语言:Rust, Dart协议类型:GNU Affero General Public Li…...
【Hive入门】Hive分桶表深度解析:从哈希分桶到Join优化的完整指南
目录 引言 1 分桶表基础概念 1.1 什么是分桶表 1.2 分桶与分区的区别 2 分桶表设计与创建 2.1 创建分桶表语法 2.2 分桶键选择原则 2.3 桶数确定策略 3 分桶表数据加载 3.1 标准数据加载流程 3.2 分桶表数据验证 4 分桶Join优化原理 4.1 Map端Join优化 4.2 Sort-…...
django之优化分页功能(利用参数共存及封装来实现)
优化分页功能 目录 1.封装分页代码 2.解决分页时覆盖搜索参数的bug 3.优化分页功能 上一篇文章我们讲到了搜索功能和分页展示数据功能。那这篇文章, 在上篇文章的基础上, 会去优化这些功能并解决搜索功能和分页功能不能一起使用的bug。 一、封装分页代码 原本我们的asse…...
linux blueZ 第四篇:BLE GATT 编程与自动化——Python 与 C/C++ 实战
本篇聚焦 BLE(Bluetooth Low Energy)GATT 协议层的编程与自动化实践,涵盖 GATT 基础、DBus API 原理、Python(dbus-next/bleak)示例、C/C++ (BlueZ GATT API)示例,以及自动发现、读写特征、订阅通知、安全配对与脚本化测试。 目录 BLE GATT 基础概念 BlueZ DBus GATT 模…...
前端面试每日三题 - Day 16
这是我为准备前端/全栈开发工程师面试整理的第16天每日三题练习,涵盖事件循环深入解析 、Vue3 响应式系统原理 ,以及 多租户系统设计实践。每道题附带 详细解析、示例代码与脑图建议,助你全面掌握底层原理与架构设计思维。 ✅ 题目 1…...
使用PyTorch实现简单图像识别(基于MNIST手写数字数据集)的完整代码示例,包含数据加载、模型定义、训练和预测全流程
以下是一个使用PyTorch实现简单图像识别(基于MNIST手写数字数据集)的完整代码示例,包含数据加载、模型定义、训练和预测全流程: import torch import torch.nn as nn import torch.optim as optim import torchvision import torc…...
【Android】四大组件之Activity
目录 一、什么是Activity 二、如何创建和配置Activity 三、Activity 跳转与数据传递 四、数据保存与恢复 五、Activity 启动模式 六、自定义返回行为 七、复杂界面布局 你可以把Activity想象成手机屏幕上的一个“页面”。比如,当你打开一个App时,…...
数据库原理(1)
第一章 概论 一、基本概念 数据(Data)是数据库中存储的基本对象,描述事物的符号记录。例如学生的学号、姓名等信息都是数据。 数据库(Database,DB)长期存储在计算机内、有组织的、可共享的大量数据的集合。…...
SQL盲注问题深度解析与防范策略
引言 在当今互联网时代,Web应用程序的安全性是重中之重。SQL注入作为一种常见且极具威胁性的攻击手段,而其中的SQL盲注更是因其隐蔽性强、难以察觉而备受关注。攻击者借助SQL盲注,在无法直接获取数据库返回结果的情况下,通过精心构造特殊的SQL语句,利用页面的不同响应来逐…...
Android JIT( ART即时编译器),Just In Time Compiler,即时编译技术
Android JIT( ART即时编译器),Just In Time Compiler,即时编译技术 Android Runtime (ART) 包含一个具备代码分析功能的即时 (JIT) 编译器,该编译器可以在 Android 应用运行时持续提高其性能。JIT是Just In Time Compiler…...
当自动驾驶遇上“安全驾校”:NVIDIA如何用技术给无人驾驶赋能?
自动驾驶技术的商业化落地,核心在于能否通过严苛的安全验证。国内的汽车企业其实也在做自动驾驶,但是吧,基本都在L2级别。换句话说就是在应急时刻内,还是需要人来辅助驾驶,AI驾驶只是决策层,并不能完全掌握…...
Unity中数据储存
在Unity项目开发中,会有很多数据,有需要保存到本地的数据,也有直接保存在缓存中的临时数据,一般为了方便整个项目框架中各个地方能调用需要的数据,因此都会实现一个数据工具或者叫数据管理类,用来管理项目中所有的数据。 首先保存在缓存中的数据,比如用户信息,我们只需…...
【C++11】可变参数模板
前言: 上文我们学到右值引用及其移动语义,学习到了C11中对性能提升对重要的更新之一。C11进阶之路:右值引用和移动语义,让代码跑得更快!-CSDN博客 本文我们来讲讲,C11的下一个新语法:可变参数模…...
c语言知识整理
一 数据的存储 对于整形的存储 无论是正负在存储中都是使用补码进行存储的 那个一个数字的补码在转换正负时不同的 对于存储中 首位一定是符号位 如果是0 那么是正数 如果是1 那么是负数 (32位 除符号位 缺少的位数使用0补齐) 如果是正数 …...
算法习题-力扣446周赛题解
算法可以调度思维,让程序员的思维发散,找到更好的解决方案。 第一题:执行指令后的得分 题目: 给你两个数组:instructions 和 values,数组的长度均为 n。你需要根据以下规则模拟一个过程: 从下标…...
基于共享上下文和自主协作的 RD Agent 生态系统
在llmangentmcp这个框架中: LLM: 依然是智能体的“大脑”,赋予它们理解、推理、生成和规划的能力,并且也用于处理和利用共享上下文。Agent: 具备特定 R&D 职能的自主单元,它们感知共享上下文࿰…...
Operating System 实验五 进程管理编程实验
实验目标: 写个多线程的程序,重现竞争条件,并通过信号量或者互斥量,解决临界区问题某工厂有两个生产车间和一个装配车间,两个生产车间分别生产A、B两种零件,装配车间的任务是把A、B两种零件组装成产品。两个生产车间每生产一个零件后,都要分别把它们送到装配车间的货架F…...
Deep Reinforcement learning for real autonomous mobile robot navigation
https://www.youtube.com/watch?vKyA2uTIQfxw AI Learns to Park - Deep Reinforcement Learning https://www.youtube.com/watch?vVMp6pq6_QjI Q Learning simply explained | SARSA and Q-Learning Explanation https://www.youtube.com/watch?vMI8ByADM…...
计算机网络 | 应用层(4)--DNS:因特网的目录服务
💓个人主页:mooridy-CSDN博客 💓文章专栏:《计算机网络:自定向下方法》 大纲式阅读笔记_mooridy的博客-CSDN博客 🌹关注我,和我一起学习更多计算机网络的知识 🔝🔝 目录 …...
WPF核心技术解析与使用示例
WPF核心技术解析与使用示例 一、依赖属性(Dependency Property)详解 1. 依赖属性基础 核心概念: 依赖属性是WPF实现数据绑定、样式、动画等特性的基础通过属性系统实现高效的内存管理和值继承标准定义模式: public class MyControl : Control {// 1. 定义…...
JVM运行机制全景图:从源码到执行的全过程
JVM运行机制全景图:从源码到执行的全过程 引言:你真的了解 Java 是怎么跑起来的吗? 许多开发者写完 Java 代码之后,就交给编译器和运行时去“神奇”地执行了。但你有没有想过,一段 .java 文件是如何一步步变成可运行的程序?今天,我们就从 源码 ➝ 字节码 ➝ 类加载 ➝…...
使用 AFL++ 对 IoT 二进制文件进行模糊测试 - 第二部分
在上一部分中,我们研究了如何使用 AFL++ 对简单的物联网二进制文件进行模糊测试。这些程序接受来自文件的输入,并且易于模糊测试。 在本文中,我们将研究套接字二进制文件。使用套接字进行网络通信的模糊测试二进制文件与使用基于文件 I/O 的模糊测试二进制文件不同。Vanill…...
在华为云平台上使用 MQTT 协议:构建高效可靠的物联网通信
🌐 在华为云平台上使用 MQTT 协议:构建高效可靠的物联网通信 随着物联网(IoT)技术的发展,设备间的高效通信变得尤为重要。MQTT(Message Queuing Telemetry Transport)作为一种轻量级的消息传输…...
基于STM32的物流搬运机器人
功能:智能循迹、定距夹取、颜色切换、自动跟随、自动避障、声音夹取、蓝牙遥控、手柄遥控、颜色识别夹取、循迹避障、循迹定距…… 包含内容:完整源码、使用手册、原理图、视频演示、PPT、论文参考、其余资料 资料只私聊...
H.264/AVC标准主流开源编解码器编译说明
An artisan must first sharpen his tools if he is to do his work well. 工欲善其事,必先利其器. 前言 想研究和学习H.264/AVC视频编解码标准的入门的伙伴们,不论是学术研究还是工程应用都离不开对源码的分析,因此首要工作是对各类编解码器进行编译,本文针对主流的一些符…...
Xilinx FPGA支持的FLASH型号汇总
以博主这些年的FPGA开发使用经验来看,FPGA开发的主流还是以Xilinx FPGA为主,贸易战关税战打了这么多年,我们做研发的也不可避免的要涉及一些国产替代的工作;这里把Xilinx FPGA官方支持的各类(国产和非国产)…...
【C++ 类和数据抽象】消息处理示例(1):从设计模式到实战应用
目录 一、数据抽象概述 二、消息处理的核心概念 2.1 什么是消息处理? 2.2 消息处理的核心目标 三、基于设计模式的消息处理实现 3.1 观察者模式(Observer Pattern) 3.2 命令模式(Command Pattern) 四、实战场景…...
LiveCharts.WPF图表模块封装
WPF LiveCharts.WPF 封装实现 下面是一个完整的 WPF LiveCharts.WPF 封装实现,提供了常用图表的简单使用方式,并支持数据绑定和更新。 一、LiveCharts.WPF 封装类 1. 图表基类 (ChartBase.cs) using LiveCharts; using LiveCharts.Wpf; using System.Collections.Generic;…...
微信小程序,基于uni-app的轮播图制作,轮播图本地文件图片预览
完整代码 <template><swiper class"banner" indicator-dots circular :autoplay"false"><swiper-item v-for "item in picture" :key"item.id"><view><image tap"onPreviewImage(item.img)" :…...
【QQmusic】复习笔记第四章分点讲解
4.1 音乐加载 功能概述 该部分实现了从本地磁盘加载音乐文件到程序中,并在界面上显示的功能。通过QFileDialog类创建文件选择对话框,用户可选择多个音乐文件,程序筛选出有效音频文件后,交由MusicList类管理,并更新到…...
设置右键打开VSCode
在日常的开发工作中,VSCode 是一款非常受欢迎的代码编辑器。为了更加便捷地使用它,我们可以将 VSCode 添加到右键菜单中,这样只需右键点击文件或文件夹,就能快速用 VSCode 打开,极大地提高工作效率。下面我就来介绍一下…...
数据结构和算法(八)--2-3查找树
目录 一、平衡树 1、2-3查找树 1.1、定义 1.2、查找 1.3、插入 1.3.1、向2-结点中插入新键 1.3.2、向一棵只含有一个3-结点的树中插入新键 1.3.3、向一个父结点为2-结点的3-结点中插入新键 1.3.4、向一个父结点为3-结点的3-结点中插入新键 1.3.5、分解根结点 1.4、2…...
JSAPI2.4——正则表达式
一、语法 const str 一二三四五六七八九十 //判断内容 const reg /二/ //判断条件 console.log(reg.test(str)); //检查 二、test与exec方法的区别 test方法:用于判断是否符合规则的字符串,返回值是布尔值 exec方法&…...
FPGA 100G UDP纯逻辑协议栈
随着器件等级的升高,高速serdes的线速率也随之提高,RFSOC 4x最大可支持100G,主流方案为RDMA方案,该方案相对比较复杂,除了需要负责逻辑端的开发,还需操作系统中开发RDMA的驱动,对于对丢包不那么…...
分享一个可以批量巡检GET和POST接口的Shell脚本
一、场景痛点与需求分析 在分布式系统架构中,服务接口的可用性和稳定性直接影响业务连续性。当面临以下场景时,需批量巡检GET和POST接口: 上线验证:新版本发布后批量验证核心接口 故障恢复:异常数据修复后的批量重试…...
机器学习之一:机械式学习
正如人们有各种各样的学习方法一样,机器学习也有多种学习方法。若按学习时所用的方法进行分类,则机器学习可分为机械式学习、指导式学习、示例学习、类比学习、解释学习等。这是温斯顿在1977年提出的一种分类方法。 有关机器学习的基本概念,…...
区分PROJECT_SOURCE_DIR, CMAKE_SOURCE_DIR,CMAKE_CURRENT_SOURCE_DIR
目录 示例工程 PROJECT_SOURCE_DIR的行为 CMAKE_SOURCE_DIR的行为 CMAKE_CURRENT_SOURCE_DIR 示例工程 根目录 |-----CMakeLists.txt |-----sub1 |--------CMakeLists.txt |-----sub2 |--------CMakeLists.txt 根目录下的CMakeList.txt: project(main)message("main …...
Python循环结构深度解析与高效应用实践
引言:循环结构在编程中的核心地位 循环结构作为程序设计的三大基本结构之一,在Python中通过while和for-in两种循环机制实现迭代操作。本文将从底层原理到高级应用,全面剖析Python循环机制的使用技巧与优化策略,助您掌握高效迭代的…...
25【干货】在Arcgis中根据字段属性重新排序并自动编号的方法(二)
上一篇关于属性表自动编号的文章因为涉及到代码(【干货】在Arcgis中根据字段属性重新排序并自动编号的方法(一)),担心大家有些东西确实不熟悉,今天就更新一篇不需要代码也能达到这个目的的方法。主要的思路…...
SinSR模型剪枝实验报告
SinSR模型剪枝实验报告 实验概述 我成功地对SinSR模型进行了L1范式剪枝,剪枝比例为50%。通过分析剪枝前后的模型参数和性能,我们得出了以下结论。 剪枝实现方法 创建专用的main_prune.py脚本,用于剪枝训练。创建quick_prune.py脚本&#…...
IT社团分析预测项目(pandas、numpy、sklearn)
IT社团人数的增长陷入迟滞,同时不同目标任务和不同经营模式的社团更是层出不穷。在面临内忧外患的情况下,本社团希望结合社团行业现状,分析同学和出勤的数据,挖据数据中的信息,通过对人数流失进行预测寻找到相应的对策…...
C语言中位段的应用
一,位段的主要应用场景 硬件寄存器操作 嵌入式开发中,硬件寄存器通常以位为单位控制设备状态。位段可直接映射到寄存器,简化位操作: typedef struct {unsigned int enable : 1; // 使能位unsigned int mode : 3; // 模式选择&…...
【Linux网络#1】:网络基础知识
1、网络发展 在计算机发展历程中,经历过下面四个阶段: 1.独立模式 独立模式:计算机之间相互独立,每台计算机做自己的事情,彼此之间没有直接信息传递。如果两台计算机需要通信就需要将当前计算机的数据通过某种方式拷贝…...
基于物联网的园林防火监测系统
标题:基于物联网的园林防火监测系统 内容:1.摘要 随着全球气候变化和人类活动影响,园林火灾发生频率呈上升趋势,给生态环境和人类生命财产造成巨大损失。为有效预防和应对园林火灾,本文提出基于物联网的园林防火监测系统。该系统综合运用传感…...
华为云loT物联网介绍与使用
🌐 华为云 IoT 物联网平台详解:构建万物互联的智能底座 随着万物互联时代的到来,物联网(IoT)已成为推动数字化转型的关键技术之一。华为云 IoT 平台(IoT Device Access)作为华为云的核心服务之…...