【Rust】——所有权:Stack(栈内存)vs Heap(堆内存)(重点)

简介: 【Rust】——所有权:Stack(栈内存)vs Heap(堆内存)(重点)

🎯官方解释

       所有权(系统)是 Rust 最为与众不同的特性,对语言的其他部分有着深刻含义。它让 Rust 无需垃圾回收(garbage collector)即可保障内存安全,因此理解 Rust 中所有权如何工作是十分重要的。本章,我们将讲到所有权以及相关功能:借用(borrowing)、slice 以及 Rust 如何在内存中布局数据。

       所有程序都必须管理其运行时使用计算机内存的方式。一些语言中具有垃圾回收机制,在程序运行时有规律地寻找不再使用的内存;在另一些语言中,程序员必须亲自分配和释放内存。Rust 则选择了第三种方式:通过所有权系统管理内存,编译器在编译时会根据一系列的规则进行检查。如果违反了任何这些规则,程序都不能编译。在运行时,所有权系统的任何功能都不会减慢程序。


🎯共同点

栈和堆都是代码在运行时可供使用的内存,但是它们的结构不同。


🎯区别

🥽栈的特点

       栈以放入值的顺序存储值并以相反顺序取出值。这也被称作 后进先出(last in, first out)。


       增加数据叫做 进栈(pushing onto the stack),而移出数据叫做 出栈(popping off the stack)。

       栈中的所有数据都必须占用已知且固定的大小。


       入栈比在堆上分配内存要快,因为(入栈时)分配器无需为存储新数据去搜索内存空间;其位置总是在栈顶。


       当你的代码调用一个函数时,传递给函数的值(包括可能指向堆上数据的指针)和函数的局部变量被压入栈中。当函数结束时,这些值被移出栈。


🥽堆的特点

       在编译时大小未知或大小可能变化的数据,要改为存储在堆上。


       堆是缺乏组织的:当向堆放入数据时,你要请求一定大小的空间。


       内存分配器(memory allocator)在堆的某处找到一块足够大的空位,把它标记为已使用,并返回一个表示该位置地址的 指针(pointer)。这个过程称作 在堆上分配内存(allocating on the heap),有时简称为 “分配”(allocating)。


       在堆上分配内存则需要更多的工作,这是因为分配器必须首先找到一块足够存放数据的内存空间,并接着做一些记录为下一次分配做准备。


       访问堆上的数据比访问栈上的数据慢,因为必须通过指针来访问。现代处理器在内存中跳转越少就越快(缓存)。


🎯所有权存在的原因

  • 所有权解决的问题:

       -跟踪代码的哪些部分正常使用heap的哪些数据。


       -最小化heap上的重复数据量。


       -清理heap上未使用的数据,以免空间不足。


  • 一旦你懂的了所有权,那么就不需要经常去想stack或heap了。
  • 但是知道管理heap数据是所有权存在的原因,这有助于解释它为什么这样工作。
相关文章
|
5天前
|
存储
栈内存
栈内存归属于单个线程,也就是每创建一个线程都会分配一块栈内存,而栈中存储的东西只有本线程可见,属于线程私有。 栈的生命周期与线程一致,一旦线程结束,栈内存也就被回收。 栈中存放的内容主要包括:8大基本类型 + 对象的引用 + 实例的方法
11 1
|
1月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
62 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
2月前
|
缓存 Java 测试技术
谷粒商城笔记+踩坑(11)——性能压测和调优,JMeter压力测试+jvisualvm监控性能+资源动静分离+修改堆内存
使用JMeter对项目各个接口进行压力测试,并对前端进行动静分离优化,优化三级分类查询接口的性能
谷粒商城笔记+踩坑(11)——性能压测和调优,JMeter压力测试+jvisualvm监控性能+资源动静分离+修改堆内存
|
1月前
|
存储 Rust 安全
Rust 中的动态内存分配
【10月更文挑战第10天】在Rust中,动态内存分配主要用于运行时按需分配内存,与静态分配不同,它能处理大小不确定的数据结构。Rust通过`Box`类型实现堆分配,`Vec`类型则用于动态数组,两者均内置智能内存管理。`Rc`和`Arc`提供引用计数机制,支持数据共享并确保内存安全。Rust的内存安全管理机制有效避免了悬空指针和双重释放等问题。
|
1月前
|
C++
析构造函数就是为了释放内存,就是在局部指针消失前释放内存,拷贝构造函数就是以构造函数为模块,在堆里面新开一块,同一个变量在堆里面的地址
本文讨论了C++中构造函数和析构函数的作用,特别是它们在管理动态内存分配和释放中的重要性,以及如何正确地实现拷贝构造函数以避免内存泄漏。
37 2
|
1月前
|
算法 Java
JVM进阶调优系列(3)堆内存的对象什么时候被回收?
堆对象的生命周期是咋样的?什么时候被回收,回收前又如何流转?具体又是被如何回收?今天重点讲对象GC,看完这篇就全都明白了。
|
3月前
|
数据采集 Rust 安全
Rust在网络爬虫中的应用与实践:探索内存安全与并发处理的奥秘
【8月更文挑战第31天】网络爬虫是自动化程序,用于从互联网抓取数据。随着互联网的发展,构建高效、安全的爬虫成为热点。Rust语言凭借内存安全和高性能特点,在此领域展现出巨大潜力。本文探讨Rust如何通过所有权、借用及生命周期机制保障内存安全;利用`async/await`模型和`tokio`运行时处理并发请求;借助WebAssembly技术处理动态内容;并使用`reqwest`和`js-sys`库解析CSS和JavaScript,确保代码的安全性和可维护性。未来,Rust将在网络爬虫领域扮演更重要角色。
77 1
|
3月前
|
Rust 网络协议 安全
揭开Rust网络编程的神秘面纱:全新的Socket体验,让你告别内存泄漏的噩梦!
【8月更文挑战第31天】Rust语言凭借其卓越的内存安全性和高性能,在网络编程领域展现出独特优势。本文将带你探索Rust中的Socket编程,展示如何使用标准库`std::net`模块轻松实现TCP服务器与客户端。通过简洁的代码示例,你将看到Rust如何简化网络通信流程,并通过`async/await`异步模型高效处理并发连接。此外,Rust社区提供的优秀库如`tokio`和`async-std`进一步增强了异步网络编程的能力。无论是从基础示例还是高级应用,Rust都将为你带来耳目一新的网络编程体验。
268 0
|
3月前
|
Rust 安全 程序员
揭秘Rust语言的内存安全秘籍:如何构建坚不可摧的系统级应用?
【8月更文挑战第31天】Rust语言凭借其独特内存安全机制在编程领域脱颖而出,通过所有权、借用与生命周期等概念,在保证高性能的同时避免了缓冲区溢出等常见错误。本文深入探讨Rust的内存安全机制,并通过示例代码展示如何利用这些机制构建高效且可靠的系统。尽管这些机制增加了学习难度,但为软件开发奠定了坚实基础,使Rust成为系统、嵌入式及网络编程的理想选择。随着社区的发展,Rust将在未来软件开发中扮演更重要角色。
85 0
|
3月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
370 0