搞嵌入式开发,最容易引起 bug 就是内存这一块。换句话说,搞嵌入式开发,做好内存管理尤为重要。
今天就来分享一款使用于嵌入式的开源内存分配器:jemalloc
开源地址:
https://github.com/jemalloc/j...
1、jemalloc 介绍
jemalloc 是一款高性能、开源的内存分配器,其用到的核心技术有如下四点:
- 大小类策略:将不同的内存块大小划分为多个类别,每个类别都有特定的分配和回收策略,可避免小对象分配导致的大内存浪费。
- 区域划分:把内存分割成独立的区域,每个区域负责一部分大小类的分配,减少了锁的竞争,提高了并发性能。
- 运行时配置:允许动态调整参数以适应不同的工作负载,如线程局部缓存的大小,进一步优化性能。
- 统计信息:提供详细的内存使用统计,帮助开发者识别内存问题,进行性能调优。
主要特点
- 并发友好:通过细粒度的锁和无锁数据结构,在多线程环境下表现出优秀的性能,能有效减少锁竞争。
- 低碎片化:精心设计的分配算法可减少内存碎片,延长程序的运行时间,提高内存利用率。
- 可定制性:提供多种配置选项,可以根据实际需求进行调整,满足不同应用场景的要求。
- 跨平台:支持多种操作系统,包括 Linux、Windows、FreeBSD 等,具有良好的可移植性。
- 丰富的工具集:内置诊断工具和统计功能,便于调试和性能监控,有助于开发者快速定位和解决内存相关的问题。
应用场景
- 高并发服务:特别适合用于 Web 服务器、数据库等需要处理大量并发请求的应用,能提升系统的并发处理能力和响应速度。
- 资源受限的设备:通过精细化内存管理,可在有限的内存资源上最大化程序性能,适用于嵌入式系统等资源受限的场景。
- 内存敏感的应用:对于需要严格控制内存消耗或防止内存泄漏的软件,如金融交易系统、航空航天控制系统等,是一个理想的选择。
2、jemalloc VS malloc
Jemalloc 和 glibc 中的 malloc 各有特点,在选择时可以考虑以下几个方面:
性能特点
- Jemalloc:在处理大规模内存分配和释放时性能出色,尤其是在多线程环境下,能有效减少内存碎片,提升内存分配效率,降低锁竞争。如在 Facebook 的大规模服务器应用中,使用 Jemalloc 显著提升了内存管理效率。
- glibc 中的 malloc:通用性强,能满足大多数应用基本的内存分配需求,在单线程或线程竞争不激烈场景下性能较好,但多线程高并发时,锁机制可能导致一定性能瓶颈。
适用场景
- Jemalloc:适合大规模多线程并发的服务器应用、数据库系统、高性能计算等对内存管理要求高的场景。像 Redis 数据库,在某些部署场景下使用 Jemalloc 可优化内存管理。
- glibc 中的 malloc:适用于一般的 C/C++应用程序,如小型桌面应用、简单的命令行工具等,对内存管理性能要求不特别苛刻的场景。
可定制性与功能特性
- Jemalloc:提供丰富的配置选项和统计信息接口,可根据具体需求精细调整内存管理策略,如自定义内存分配器的行为、获取详细内存使用统计数据。
- glibc 中的 malloc:功能相对较为基础,虽能满足常见内存分配需求,但可定制性和高级功能不如 Jemalloc。
兼容性与可移植性
- Jemalloc:在大多数主流操作系统上可使用,但在某些小众或特定嵌入式系统中可能存在兼容性问题。
- glibc 中的 malloc:与 Linux 系统紧密集成,在 Linux 平台上兼容性和可移植性好,几乎所有 Linux 系统都提供且能稳定工作。
如果是开发高性能、大规模多线程的应用,对内存管理要求高且希望有更多定制功能,Jemalloc 是较好选择;对于一般的 C/C++应用,追求简单通用和良好的系统兼容性,glibc 中的 malloc 通常能满足需求。
3、简单使用
Jemalloc 在 C 语言中使用步骤及简单示例:
安装 Jemalloc
在使用 Jemalloc 之前,需要先进行安装。可以通过包管理工具,如在 Ubuntu 系统下使用apt-get
命令安装:sudo apt-get install libjemalloc-dev
,在 CentOS 系统下可以使用yum
命令:sudo yum install jemalloc-devel
。也可以从 Jemalloc 的官方网站(https://jemalloc.net/)下载源代码,然后进行编译安装。
引入头文件
在 C 语言源文件中,需要引入 Jemalloc 的头文件jemalloc/jemalloc.h
,这样才能使用 Jemalloc 提供的函数和相关类型定义。示例如下:
#include <jemalloc/jemalloc.h>
#include <stdio.h>
int main() {
// 使用 Jemalloc 分配内存
int *ptr = (int *)je_malloc(sizeof(int));
if (ptr == NULL) {
printf("内存分配失败\n");
return 1;
}
// 使用分配的内存
*ptr = 42;
printf("分配的内存中存储的值: %d\n", *ptr);
// 释放内存
je_free(ptr);
return 0;
}
链接库文件
在编译时,需要链接 Jemalloc 库。如果使用gcc
编译,可以使用-ljemalloc
选项来链接 Jemalloc 库,假设上述代码保存在test.c
文件中,编译命令如下:gcc -o test test.c -ljemalloc
END
来源:strongerHuang
推荐阅读
欢迎大家点赞留言,更多 Arm 技术文章动态请关注极术社区嵌入式客栈专栏欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。