PhysX 块分配器:内存批发模式与子分配原理 📅 发布时间:2026/9/2 17:39:57 👁 浏览次数: 开场做物理游戏时,我遇到过一个诡异问题:子弹命中目标瞬间,引擎帧率从 60 直接掉到 15。Profiler 一查,内存分配堆里全是malloc/free,每次射击产生几十上百次PxShape、PxMaterial的创建与销毁。GC 没背锅,C++ 这边却在疯狂调系统分配器——这就是物理引擎在高频对象创建场景下的典型翻车现场。更糟的是,简单把底层换成 jemalloc 后,内存占用反而涨了 30%。后来翻 PhysX 的公开头文件和文档才明白:真正的问题不是分配器不够快,而是分配粒度太细。PhysX 的解法非常朴素也非常有效:自己搞批发,不跟系统零售。一、先搞清楚:零售式 malloc 到底贵在哪在讨论"批发"之前,先得知道"零售"的账单。一次malloc(64)远不止"找块内存"那么简单:锁竞争:glibc 等系统分配器内部有 arena 和锁,多线程同时分配会排队。簿记开销:每个分配块都要带头部元数据(大小、链表指针),64 字节的对象可能实际占 80~96 字节。页错误:新映射的虚拟内存第一次写入时触发 page fault,内核介入,微秒级延迟。缓存不友好:前后两次分配的对象在地址空间上可能隔着几个页面,物理模拟这种"遍历上千个刚体"的访问模式会把 CPU 缓存和 TLB