Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Catalog · How the catalog works
Anything · Lazarus or Delphi
Random projectRandom project

mimalloc4p

mimalloc for Pascal – 为 Delphi / FreePascal 提供高性能内存分配支持

View on GitHub

Member rating

No ratings yet.

Sign in to rate this project.

README

mimalloc4p

mimalloc for Pascal – 为 Delphi / FreePascal 提供高性能内存分配支持

mimalloc4p 是 microsoft/mimalloc 的 Pascal 语言绑定。通过简单的单元引用,即可让你的 Delphi 或 FreePascal 程序挂载 mimalloc 内存分配器,获得高性能、低碎片的多线程内存管理能力。

mimalloc 是微软开源的高性能内存分配器,在多线程场景下性能优于 jemalloc 和 tcmalloc,且代码精简(约 10k LOC)。


系统支持

  • Windows (32-bit / 64-bit) —— 提供预编译 DLL
  • Linux (x64, ARM, MIPS) —— 需自行编译
  • FreeBSD / OpenBSD / NetBSD —— 需自行编译
  • macOS (OS X) —— 需自行编译
  • 其他 POSIX 系统(支持 CMake)

编译器和 IDE 支持

  • Delphi XE10 及以上版本
  • FreePascal (FPC) 3.0+
  • CodeTyphon
  • Lazarus

为什么选择 mimalloc4p

  • 原生 Windows 支持:mimalloc 是微软出品,对 Windows 平台的支持和优化是 jemalloc 无法比拟的。
  • 性能卓越:在各类基准测试中表现优于 jemalloc、tcmalloc 等主流分配器。
  • 多线程优化:创新的多分片自由列表设计,降低线程间竞争。
  • 代码简洁:mimalloc 核心代码约 10k LOC,比 jemalloc 轻量得多。
  • 跨平台:原生支持 Windows、macOS、Linux、各种 BSD、WASM、Haiku、MUSL 等。
  • 我的开源项目 ZServer4D / ZAI / zAnalysis:这些库在多平台部署时,一个高性能、统一的内存管理器是刚需。

构建与获取动态库

Windows

Windows 平台使用预编译动态库,本仓库已附带:

  • 32 位:mimalloc32.dll
  • 64 位:mimalloc64.dll

直接引用 mimalloc4p.pas 单元即可自动选择对应架构。

⚠️ 运行环境依赖:
预编译 DLL 使用 Visual Studio 2022 编译,运行时需要安装 VS2022 可再发行组件(VC++ Redistributable)。
请从微软官方下载并安装对应架构的版本:


Linux

Linux 下需要自行编译生成 libmimalloc.so,并让程序能够加载。推荐将编译好的动态库部署到项目目录,避免污染系统环境。

1. 安装依赖

bash
# Debian / Ubuntu
sudo apt-get update
sudo apt-get install git cmake build-essential

# CentOS / RHEL / Fedora
sudo yum install git cmake gcc-c++ make      # CentOS 7
sudo dnf install git cmake gcc-c++ make      # Fedora / RHEL 8+

2. 克隆并编译

bash
git clone https://github.com/microsoft/mimalloc.git
cd mimalloc
git checkout v2.1.7   # 推荐使用稳定版本(也可用最新 tag)
mkdir build && cd build
cmake .. -DMI_BUILD_SHARED=ON   # 确保生成动态库
make -j$(nproc)

编译完成后,build 目录下会出现:

  • 真正的动态库文件:libmimalloc.so.2.4(版本号可能不同)
  • 符号链接:libmimalloc.so.2 → libmimalloc.so.2.4
  • 符号链接:libmimalloc.so → libmimalloc.so.2

3. 部署到项目目录(推荐)

将动态库及其符号链接完整复制到你的 Pascal 项目输出目录(或统一的 lib 子目录)。假设你的可执行文件存放在 ~/myapp/:

bash
# 复制到可执行文件所在目录
cp -a libmimalloc.so.2.4 ~/myapp/
cp -a libmimalloc.so.2 ~/myapp/
cp -a libmimalloc.so ~/myapp/

# 或者复制到子目录 lib/ 中
mkdir -p ~/myapp/lib
cp -a libmimalloc.so.2.4 ~/myapp/lib/
cp -a libmimalloc.so.2 ~/myapp/lib/
cp -a libmimalloc.so ~/myapp/lib/

4. 让程序找到动态库

程序运行时,系统必须能找到 libmimalloc.so。常见方法如下(任选其一):

方法 A:运行时设置环境变量(临时)

bash
# 如果库与可执行文件同目录
LD_LIBRARY_PATH=. ./myapp

# 如果库放在 lib/ 子目录
LD_LIBRARY_PATH=./lib ./myapp

方法 B:编译时写入 RPATH(一劳永逸,强烈推荐)

使用 FreePascal 编译时,通过 -k 向链接器传递 -rpath 选项,使程序自动在指定路径查找动态库。

  • 库与可执行文件同目录:
    bash
    fpc -k'-rpath=$ORIGIN/' yourprogram.pas
  • 库在 lib 子目录:
    bash
    fpc -Fl./lib -k'-rpath=$ORIGIN/lib' yourprogram.pas

$ORIGIN 表示可执行文件自身所在的目录。编译后可用 readelf -d myapp | grep RPATH 验证 RPATH 是否生效。

方法 C:安装到系统目录(全局可用)

bash
sudo make install   # 默认安装到 /usr/local/lib
sudo ldconfig        # 更新动态链接器缓存

之后所有程序都能直接使用,但可能与其他软件冲突,生产环境不推荐。

5. 验证库是否正常工作

你可以用一段简单的 C 代码测试编译好的动态库是否能正常加载:

c
// test.c
#include <mimalloc.h>
#include <stdio.h>
int main() {
    void* p = mi_malloc(64);
    if (p) {
        printf("mimalloc works!\n");
        mi_free(p);
        return 0;
    }
    return 1;
}

编译并运行:

bash
# 注意:-I 指向 mimalloc 源码的 include 目录,-L. 指向 build 目录
gcc test.c -I../include -L. -Wl,-rpath=. -lmimalloc -lpthread -lrt -o test
./test

如果输出 mimalloc works!,说明动态库构建成功且可正常使用。

你也可以直接运行 mimalloc 自带的测试套件(需在 build 目录下):

bash
cmake .. -DMI_BUILD_TESTS=ON
make -j$(nproc)
ctest

BSD(FreeBSD / OpenBSD / NetBSD)

FreeBSD(推荐使用 Ports)

bash
pkg install mimalloc

或从 Ports 编译:

bash
cd /usr/ports/devel/mimalloc
make install clean

从源码编译(通用)

与 Linux 相同,使用 CMake:

bash
git clone https://github.com/microsoft/mimalloc.git
cd mimalloc
mkdir -p build && cd build
cmake .. -DMI_BUILD_SHARED=ON
make -j4
sudo make install

如果 BSD 系统缺少 CMake,先安装:pkg install cmake(FreeBSD)或 pkg_add cmake(OpenBSD)。


macOS(OS X)

编译方式与 Linux / BSD 一致,生成 libmimalloc.dylib:

bash
git clone https://github.com/microsoft/mimalloc.git
cd mimalloc
mkdir -p build && cd build
cmake .. -DMI_BUILD_SHARED=ON
make -j4
sudo make install

使用说明

在 Delphi 或 FreePascal 工程中引用 mimalloc4p.pas 单元即可自动挂载内存管理器:

pascal
program MyApp;

uses
  mimalloc4p,  // 建议放在第一个 uses
  Forms,
  Unit1;

begin
  Application.Initialize;
  Application.Run;
end.

手动控制(可选)

如果需要在运行时恢复原始内存管理器(例如调试内存泄漏),可以调用:

pascal
mimalloc4p.UnInstallMemoryHook;

但务必确保调用后不再有任何 FreeMem / GetMem 操作,否则会导致崩溃。


⚠️ 重要注意事项

  1. 退出时异常风险
    当前版本的 mimalloc4p.pas 在 finalization 中会调用 UnInstallMemoryHook 恢复原始内存管理器。这可能导致全局对象析构时 FreeMem 使用了已卸载的内存管理器,从而触发访问冲突。
    强烈建议:在 mimalloc4p.pas 的 finalization 段中注释掉 UnInstallMemoryHook,让操作系统在进程退出时统一回收内存,这是最稳定可靠的做法。
    如果你必须卸载(例如为了检测内存泄漏),请确保在所有对象销毁完成之后再手动调用 UnInstallMemoryHook。
  2. GetMem(0) 行为
    当前 Delphi 版本直接调用 mi_malloc(Size),若 Size=0,mimalloc 可能返回 nil。某些代码期望 GetMem(0) 返回非 nil 指针,否则可能导致解引用崩溃。
    建议在使用 GetMem(0) 的业务代码中自行判断,或修改 do_GetMem 强制分配至少 1 字节(类似 FPC 版本)。
  3. AllocMem 清零
    Delphi 版本使用 Fast_FillByte(Result, Size, 0) 清零,FPC 版本使用 Fast_FillByte 清零整个 TotalSize。两种实现均符合各自编译器的契约。
  4. ReallocMem 与 Size=0
    FPC 版本显式处理了 Size=0 时释放原指针并返回 nil;Delphi 版本直接调用 mi_realloc,依赖于 mimalloc 的行为(通常也支持释放),但为保险起见,建议参照 FPC 写法统一处理。
  5. 线程安全
    mimalloc 原生支持多线程,无需额外配置。

更新说明

  • 2026-07:初始版本发布
  • Windows 动态库使用 Visual Studio 2022 构建
  • Linux / BSD / macOS 使用 CMake + GCC/Clang 构建

相关链接


License

本项目基于 MIT 协议开源。mimalloc 本身也采用 MIT 协议。


by qq600585