当前位置: 首页 > news >正文

Rust中的特殊类型所占的内存大小

可以使用std::mem:size_of获取类型大小:

use std::mem::size_of;struct Journal(String, u32);
trait Summary {}
impl Summary for Journal {}fn main() {println!("普通结构体相关:");println!("{}", size_of::<&Journal>());println!("{}", size_of::<Box<Journal>>());println!("特征对象相关:");println!("{}", size_of::<Box<dyn Summary>>());println!("{}", size_of::<&dyn Summary>());println!("{}", size_of::<&mut dyn Summary>());println!("{}", size_of::<*const dyn Summary>());println!("{}", size_of::<*mut dyn Summary>());println!("切片相关:");println!("{}", size_of::<&str>());println!("{}", size_of::<&[i32]>());println!("{}", size_of::<&[i32; 100]>());println!("集合相关:");println!("{}", size_of::<[i32; 100]>());println!("{}", size_of::<Vec<i32>>());println!("{}", size_of::<String>());
}

输出

普通结构体相关:
8
8
特征对象相关:
16
16
16
16
16
切片相关:
16
16
8
集合相关:
400
24
24

原因分析

Rust中,一个普通指针的大小为usize,与计算机CPU字长相等,对64位计算机来说usize=64/8=8字节

  • 对普通结构体来说,其引用/Box智能指针所占大小为usize,指示在内存中的起始位置即可,因为普通结构体编译时大小确定,运行时存放在栈上
  • 特征对象非常特殊,其引用/Box智能指针/裸指针占的大小均为2*usize
    • 这是因为特征对象编译时大小不确定,因此需要在运行时动态获知对象实例以及特征方法在内存中的位置,因此需要两个指针,分别指向它们
  • 对切片类型:
    • &str所占空间为2*usize,所引用字符串可能来自于堆内存/全局数据区,&str指示了所引用数据的起始位置和长度
    • &[i32]&str类似(&str是对&[u8]的封装),所占空间为2*usize,指示了所引用字符串在堆内存/栈内存中的起始位置和长度
    • &[i32; N]仅占一个usize,因为[i32; N]编译时大小已知,存放在栈上,&[i32; N]不需要像&[i32]那样额外记录长度
  • 对集合相关:
    • [i32; 100]编译时大小已知,存放在栈上,内存大小为4*100=400个字节
    • Vec动态数组的数据存放在堆上,Vec类型占三个usize的长度,分别指示数组在堆中的起始位置,数组长度以及数组当前的最大容量
    • String是对Vec<u8>的封装,其数据存放在堆上,String类型占三个usize的长度,分别指示字符串在堆中的起始位置,字符串长度以及字符串当前的最大长度

其实,VecString的本质都是智能指针,它们的大小都是固定的(大小不固定也没法通过编译啊),运行时存放在栈上。但是它们所包裹数据的长度是可变的,存放在堆上。它们的本质是通过存放在栈上的指针访问堆内存,来操作堆上包裹的数据。

综上所述,智能指针/引用所占内存大小是固定的,但是其指向的数据大小未必固定。对于所占内存固定已知的数据类型,运行时会把它们放在栈上,对于所占内存不固定的数据类型,运行时会把它们放在堆上,然后可以通过存放在栈上的指针来操作堆上的数据。

http://www.lryc.cn/news/413393.html

相关文章:

  • 【深度学习】变分自编码器 VAE,什么是变分?(1)
  • 宏编程:C++宏、Rust宏和Lisp宏比较
  • ChatGPT协助撰写研究论文的11种方法【全集】
  • PEP 8 – Python 代码风格指南中文版(四)
  • 基于深度学习的适应硬件的神经网络
  • 上传音频文件
  • Linux之jdk离线安装
  • JVM结构、架构与生命周期总结
  • Flink-StarRocks详解:第四部分StarRocks分区管理,数据压缩(第54天)
  • 为什么有时候银行贷款审核会查大数据信用?
  • LoRa无线通讯,让光伏机器人实现无“线”管理
  • 买流量卡要注意什么,这些冷知识你一定要懂!
  • 【嵌入式】STM3212864点阵屏使用SimpleGUI单色屏接口库——(2)精简字库
  • 《计算机网络》(第8版)第1章 概述 复习笔记
  • 银行数据质量保障体系建设实践
  • 笔记小结:《利用Python进行数据分析》二进制数据格式存储与web交互
  • 电脑桌面图标变白了?3个方法20秒钟轻松解
  • 数据治理,管什么?
  • 【前端】JavaScript入门及实战121-125
  • pytest测试框架之http协议接口测试
  • FFmpeg源码:av_gcd函数分析
  • springboot物流寄查系统-计算机毕业设计源码95192
  • 【秋招笔试】24-07-27-OPPO-秋招笔试题(算法岗)
  • AUTOSAR实战教程 - 模式管理BswM与其他各模块的交互
  • 经典非比较排序—计数排序的Java实现方式
  • 【C++从小白到大牛】栈和队列(优先级队列)
  • Golang之OpenGL(一)
  • 122. Go反射中与结构体相关的常用方法与应用
  • Java入门、进阶、强化、扩展、知识体系完善等知识点学习、性能优化、源码分析专栏分享
  • Spring-bean销毁