9 个版本

使用旧的 Rust 2015

0.4.5 2019 年 8 月 22 日
0.4.4 2019 年 4 月 15 日
0.4.3 2019 年 2 月 18 日
0.4.2 2018 年 7 月 16 日
0.2.0 2018 年 3 月 6 日

#1511 in WebAssembly

Download history 15873/week @ 2024-03-14 11762/week @ 2024-03-21 27423/week @ 2024-03-28 11848/week @ 2024-04-04 12929/week @ 2024-04-11 13303/week @ 2024-04-18 13094/week @ 2024-04-25 13444/week @ 2024-05-02 11995/week @ 2024-05-09 20060/week @ 2024-05-16 20750/week @ 2024-05-23 14443/week @ 2024-05-30 19216/week @ 2024-06-06 16575/week @ 2024-06-13 15561/week @ 2024-06-20 15072/week @ 2024-06-27

68,871 每月下载量
用于 少于 154 crates

MPL-2.0 许可证

74KB
1.5K SLoC

wee_alloc

Wasm-Enabled、Elfin 分配器

Build Status Build Status Crates.io version Download docs.rs docs

API 文档 | 贡献 | 聊天

Rust 和 WebAssembly 工作组 构建 🦀🕸

关于

wee_alloc:Wasm-Enabled、Elfin 分配器。

  • Elfin,即小巧:生成的未压缩 WebAssembly 代码小于一千字节。不包含重型的恐慌或格式化基础设施。wee_alloc 不会使您的 Web 下载 .wasm 大小膨胀。

  • WebAssembly 支持:针对 wasm32-unknown-unknown 目标和 #![no_std] 设计。

wee_alloc 主要针对 WebAssembly,生成小型 .wasm 代码,并具有简单、正确的实现。它适用于进行少量初始动态分配的代码,然后在没有进一步分配的情况下进行大量操作。这种场景需要存在某些分配器,但我们更愿意为了小代码大小而牺牲分配性能。相比之下,在分配是性能瓶颈的场景中,wee_alloc 可能不是一个好的选择。

尽管 WebAssembly 是主要目标,但 wee_alloc 也有基于 mmap 的 Unix 系统实现,Windows 的 VirtualAlloc 实现,以及适用于独立操作系统的静态数组后端。这使得可以在没有浏览器或 WebAssembly 引擎的情况下测试 wee_alloc 和使用 wee_alloc 的代码。

wee_alloc 可在稳定的 Rust 1.33 及更高版本上编译。

wee_alloc 作为全局分配器使用

extern crate wee_alloc;

// Use `wee_alloc` as the global allocator.
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;

cargo 功能

  • size_classes:默认开启。使用大小类进行较小分配,为它们提供摊销的 O(1) 分配。增加未压缩 .wasm 代码大小约 450 字节(总计约 ~1.2K)。

  • extra_assertions:启用各种额外的、昂贵的完整性断言和防御机制,例如释放内存时的毒化。这会带来很大的运行时开销。当调试 use-after-free 或 wee_alloc 本身时很有用。

  • static_array_backend:强制使用与操作系统无关的后端实现,全局最大大小在编译时固定。适用于部署到非 WASM/Unix/Windows 的独立操作系统环境,如嵌入式设备上的奇异的或实际上不存在的操作系统。默认大小为 32 MiB(33554432 字节),可以在构建时通过向 cargo 提供可选环境变量来控制,WEE_ALLOC_STATIC_ARRAY_BACKEND_BYTES。请注意,此功能需要夜间 Rust。

  • nightly:启用仅限夜间 Rust 的功能,例如实现 Alloc 特性(不要与稳定的 GlobalAlloc 特性混淆!)

实现说明和约束

  • wee_alloc 在每个分配上增加两个字节的开销,以维护其内部空闲列表。

  • 释放操作是 O(1) 操作。

  • wee_alloc 永远不会将释放的页面返回给 WebAssembly 引擎/操作系统。目前,WebAssembly 可以扩展其堆,但永远不会缩小它。所有分配的页面都无限期地保存在 wee_alloc 的内部空闲列表中,以供将来潜在的分配使用,即使是在 Unix 目标上运行也是如此。

  • wee_alloc 使用简单的、首次适应的空闲列表实现。这意味着分配是一个 O(n) 操作。

    使用 size_classes 功能可以启用专门用于小型分配(小于或等于 256 个字)的额外空闲列表。大小类的空闲列表通过从主空闲列表分配大块来填充,提供摊销的 O(1) 分配时间。从大小类空闲列表分配使用与从主空闲列表分配相同的首次适应例程,这样可以避免引入比必要的更多代码膨胀。

最后,这里有一个概述 wee_alloc 实现的图表

+------------------------------------------------------------------------------+
| WebAssembly Engine / Operating System                                        |
+------------------------------------------------------------------------------+
                   |
                   |
                   | 64KiB Pages
                   |
                   V
+------------------------------------------------------------------------------+
| Main Free List                                                               |
|                                                                              |
|          +------+     +------+     +------+     +------+                     |
| Head --> | Cell | --> | Cell | --> | Cell | --> | Cell | --> ...             |
|          +------+     +------+     +------+     +------+                     |
|                                                                              |
+------------------------------------------------------------------------------+
                   |                                    |            ^
                   |                                    |            |
                   | Large Blocks                       |            |
                   |                                    |            |
                   V                                    |            |
+---------------------------------------------+         |            |
| Size Classes                                |         |            |
|                                             |         |            |
|             +------+     +------+           |         |            |
| Head(1) --> | Cell | --> | Cell | --> ...   |         |            |
|             +------+     +------+           |         |            |
|                                             |         |            |
|             +------+     +------+           |         |            |
| Head(2) --> | Cell | --> | Cell | --> ...   |         |            |
|             +------+     +------+           |         |            |
|                                             |         |            |
| ...                                         |         |            |
|                                             |         |            |
|               +------+     +------+         |         |            |
| Head(256) --> | Cell | --> | Cell | --> ... |         |            |
|               +------+     +------+         |         |            |
|                                             |         |            |
+---------------------------------------------+         |            |
                      |            ^                    |            |
                      |            |                    |            |
          Small       |      Small |        Large       |      Large |
          Allocations |      Frees |        Allocations |      Frees |
                      |            |                    |            |
                      |            |                    |            |
                      |            |                    |            |
                      |            |                    |            |
                      |            |                    |            |
                      V            |                    V            |
+------------------------------------------------------------------------------+
| User Application                                                             |
+------------------------------------------------------------------------------+

许可证

根据 Mozilla 公共许可证 2.0 许可。

TL;DR?

本弱版权许可的权限条件是提供受许可文件的源代码及其修改(在某些情况下,为GNU许可证之一)。必须保留版权和许可声明。贡献者提供专利权的明确授予。然而,使用受许可作品的大型作品可以以不同条款进行分发,且不包含大型作品中添加的文件的源代码。

贡献

有关黑客技巧,请参阅 CONTRIBUTING.md

依赖项

~240KB