#arena #memory #heap-memory #placement #stack #allocator #copy

light_arena

为Sized + Copy类型的轻量级、基于放置的内存区域。此crate需要nightly版本。

5个版本 (2个稳定版本)

使用旧的Rust 2015

1.0.1 2019年6月15日
0.1.2 2018年1月27日
0.1.1 2017年6月24日
0.1.0 2017年6月24日

#placement中排名8

MIT许可协议

14KB
132 代码行

light_arena

暂时是一个更简单的内存池,用于将堆栈分配的对象复制到共享堆中,而不是真正的放置新内存区域。遗憾的是,Rust中放置新的路径目前看起来不太乐观,所以我将此crate改回更像是一个内存堆,可以在其中放置东西,但不能就地构造。这模仿了类似的行为,但分配限制在堆栈大小,并且必须首先在堆栈上创建,然后复制。

此crate是为了解决我在tray_rust中遇到的一个特定问题,在那里我想在内存区域中存储trait对象和f32数组,然后重置并重新使用每个渲染像素(但不释放和重新分配!)的内存区域。启用此功能的关键是使用nightly放置新功能,允许我们实际上在原地构造对象,而不是从堆栈临时复制,并通过Allocator作用域重用先前分配的空间。如果你有类似的问题,这个crate可能就是你要找的!

Crate Version Badge Build Status

示例

MemoryArena中进行的分配使用分配器和放置在语法。在作用域内,Allocator授予对区域的独占访问权限,允许进行分配。一旦Allocator被丢弃,使用的空间将再次标记为可供后续分配使用。请注意,分配在区域中的对象**永远不会调用Drop**,因此有T: Sized + Copy的限制。

#![feature(placement_in_syntax)]
use light_arena;

let mut arena = light_arena::MemoryArena::new(8);
let alloc = arena.allocator();
// This would overflow the stack without placement new!
let bytes: &[u8] = &alloc <- [0u8; 8 * 1024 * 1024];

区域是无类型的,可以存储任何是Sized + Copy的。

#![feature(placement_in_syntax)]
use light_arena;

trait Foo {
	fn speak(&self);
}

#[derive(Copy, Clone)]
struct Bar(i32);
impl Foo for Bar {
	fn speak(&self) {
		println!("Bar! val = {}", self.0);
	}
}

#[derive(Copy, Clone)]
struct Baz;
impl Foo for Baz {
	fn speak(&self) {
		println!("Baz!");
	}
}

fn main() {
	let mut arena = light_arena::MemoryArena::new(2);
	let allocator = arena.allocator();
	let a: &Foo = &allocator <- Baz;
	let b: &Foo = &allocator <- Bar(10);
	let c: &Foo = &allocator <- Bar(14);
	a.speak();
	b.speak();
	c.speak();
	// Storing 0-sized types can give some interesting results
	println!("a = {:p}", a as *const Foo);
	println!("b = {:p}", b as *const Foo);
	println!("c = {:p}", c as *const Foo);
}

文档

可以在这里找到Rustdoc

阻碍因素

依赖项

~0–1.4MB
~32K SLoC