5个版本
0.0.4 | 2019年11月29日 |
---|---|
0.0.3 | 2019年11月3日 |
0.0.2 | 2019年2月6日 |
0.0.1 | 2019年2月6日 |
0.0.0 | 2019年2月6日 |
#146 在 调试
877 每月下载量
用于 17 个crate(16个直接使用)
16KB
170 行
alloc_counter
分配计数器
快速且简单的分配分析工具的重设计。
特性
-
尽管预期使用
#[no_std]
,但由于缺少可移植的thread_local
实现,目前不支持。这可以通过使用全局原子的功能标志“修复”,前提是程序是单线程的。 -
使用
count_alloc
分别统计分配、重新分配和释放。 -
使用
allow_alloc
、deny_alloc
和forbid_alloc
允许、拒绝和禁止使用全局分配器。 -
使用函数属性
#[no_alloc]
拒绝和#[no_alloc(forbid)]
禁止使用全局分配器。 -
#[count_alloc]
函数属性用于将计数打印到 stderr。或者使用#[count_alloc(func = "my_function")]
,其中my_function
接受三个usize
的三元组并返回()
来重定向输出。
限制和已知问题
-
方法必须要么接受
self
的引用,要么Self
必须是一个Copy
类型。 -
普通和异步函数必须分别处理。使用
count_alloc
对函数进行计数,使用count_alloc_future
对未来进行计数。
用法
AllocCounter<A>
包装分配器 A
以单独计算对 alloc
、realloc
和 dealloc
的调用次数。
use alloc_counter::AllocCounter;
type MyAllocator = std::alloc::System;
const MyAllocator: MyAllocator = std::alloc::System;
#[global_allocator]
static A: AllocCounter<MyAllocator> = AllocCounter(MyAllocator);
Std-users 可能更喜欢继承其系统的分配器。
use alloc_counter::AllocCounterSystem;
#[global_allocator]
static A: AllocCounterSystem = AllocCounterSystem;
要计算表达式的分配,请使用 count_alloc
。
# use alloc_counter::{count_alloc, AllocCounterSystem};
# #[global_allocator]
# static A: AllocCounterSystem = AllocCounterSystem;
let (counts, v) = count_alloc(|| {
// no alloc
let mut v = Vec::new();
// alloc
v.push(0);
// realloc
v.push(1);
// return the vector without deallocating
v
});
assert_eq!(counts, (1, 1, 0));
要拒绝表达式的分配,请使用 deny_alloc
。
# use alloc_counter::{deny_alloc, AllocCounterSystem};
# #[global_allocator]
# static A: AllocCounterSystem = AllocCounterSystem;
fn foo(b: Box<i32>) {
// dropping causes a panic
deny_alloc(|| drop(b))
}
foo(Box::new(0));
类似于 Rust 的 lint,你仍然可以在 deny 块内允许分配。
# use alloc_counter::{allow_alloc, deny_alloc, AllocCounterSystem};
# #[global_allocator]
# static A: AllocCounterSystem = AllocCounterSystem;
fn foo(b: Box<i32>) {
deny_alloc(|| allow_alloc(|| drop(b)))
}
foo(Box::new(0));
禁止分配强制引发 panic,即使使用了 allow_alloc
。
# use alloc_counter::{allow_alloc, forbid_alloc, AllocCounterSystem};
# #[global_allocator]
# static A: AllocCounterSystem = AllocCounterSystem;
fn foo(b: Box<i32>) {
// panics because of outer `forbid`, even though drop happens in an allow block
forbid_alloc(|| allow_alloc(|| drop(b)))
}
foo(Box::new(0));
为了增加便利,你可以在函数上使用 #[no_alloc]
属性,包括具有 self 绑定的方法。 #[no_alloc]
展开为调用 deny_alloc
并强制将参数移动到检查块中。 #[no_alloc(forbid)]
调用 forbid_alloc
。
# #[cfg(not(feature = "macros"))]
# panic!("macros feature disabled");
# #[cfg(feature = "macros")] {
# use alloc_counter::{allow_alloc, no_alloc, AllocCounterSystem};
# #[global_allocator]
# static A: AllocCounterSystem = AllocCounterSystem;
#[no_alloc(forbid)]
fn foo(b: Box<i32>) {
allow_alloc(|| drop(b))
}
foo(Box::new(0));
# }
许可证:MIT OR Apache-2.0
依赖项
~220KB