微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

分配此结构后,会浪费多少内存?

如何解决分配此结构后,会浪费多少内存?

我正在Rust中基于bplus树构建索引树,到目前为止,父节点的定义如下:

struct Parent<T : std::fmt::Debug> {
    subtree_count : [usize; Arity],children      : [*mut ParentOrLeaf<T>; Arity],used          : usize,}

在我的Arity = 8的64位计算机上,计算得出的总内存需求为136个字节。我正在使用std::alloc::Layout::newstd::alloc::alloc分配此结构。但是我担心malloc库比2的幂大一点(136> 128)最终将为此数据结构分配256个字节,而不是仅分配136个字节。由于这是容器类型,浪费了一半的内存分配是不可接受的。

std::alloc::Layout::new::<Parent<T>>().align()报告的布局为8。

此结构在分配后实际上会占用多少内存?

如果浪费了太多内存,我可以将subtree_count : [usize; Arity]更改为subtree_count : [usize; Arity-1],这将使总内存为128。然后重做我库的所有优化逻辑来处理更改。但是在我这样做之前,我想确保这实际上是必要的。

解决方法

如果大小为136,则意味着数组或向量中许多结构的连续分配将为每个结构使用136个字节。

在单独分配某些结构时,浪费的空间量仅取决于基础的malloc()策略,而不是所分配类型的属性。

例如,在我的stable-x86_64-unknown-linux-gnu平台上对您的示例进行了快速而肮脏的修改,可以实现以下目的:

size 136
align 8
arr delta1 136
arr delta2 136
box delta1 144
box delta2 144

当然没有保证三个分配的结构彼此靠近,但是在这种特定情况下,它们和浪费(不是真正的浪费,而是由分配器本身使用)空间是8个字节。

struct ParentOrLeaf<T: std::fmt::Debug> {
    value: Option<T>,}

const Arity: usize = 8;

struct Parent<T: std::fmt::Debug> {
    subtree_count: [usize; Arity],children: [*mut ParentOrLeaf<T>; Arity],used: usize,}

fn main() {
    type P = Parent<i32>;
    let l = std::alloc::Layout::new::<P>();
    println!("size {}",l.size());
    println!("align {}",l.align());
    let ptr: *mut ParentOrLeaf<i32> = std::ptr::null_mut();
    let arr = [
        P {
            subtree_count: [0; Arity],children: [ptr; Arity],used: 0,},P {
            subtree_count: [0; Arity],];
    let a0 = &arr[0] as *const P as usize;
    let a1 = &arr[1] as *const P as usize;
    let a2 = &arr[2] as *const P as usize;
    println!("arr delta1 {}",a1 - a0);
    println!("arr delta2 {}",a2 - a1);
    let p0 = Box::new(P {
        subtree_count: [0; Arity],});
    let p1 = Box::new(P {
        subtree_count: [0; Arity],});
    let p2 = Box::new(P {
        subtree_count: [0; Arity],});
    let a0 = p0.as_ref() as *const P as usize;
    let a1 = p1.as_ref() as *const P as usize;
    let a2 = p2.as_ref() as *const P as usize;
    println!("box delta1 {}",a1 - a0);
    println!("box delta2 {}",a2 - a1);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。