内存对rust影响大吗 (rust限制最大内存)

rust的内存管理可视化,rust16g内存

我一直对编程语言着迷。 我总是尝试不同的编程语言,并且总是对通过选择其特性来学习内部知识感兴趣。 一次一个。 所有这些设计选择背后的故事总是令人兴奋,值得一读。

这些年来,我学习了很多编程语言,但是我并不是其中任何一种专家。 事实是我从未想过。 激励我的唯一原因是其设计背后的原因,简单地说就是"为什么要按原样设计语言?"。 是什么使它们与其他语言不同? 权衡是什么,这些设计选择有什么好处?

Rust

几周前,我尝试了Rust。 其概念之一,称为所有权,使我兴奋。 Rust编译器在内存安全性方面使用的概念有助于解决大多数其他低级编程语言所面临的空指针错误。

Rust是一种在设计时考虑到安全性的编程语言。 该语言的设计者希望Rust是安全,低级,高效和快速的。 但是问题是您只能获得低级别的控制或更高的安全性。 多年以来,程序员在处理低级内容时必须小心,诸如C和C ++之类的语言允许进行低级控制,但是开发人员必须编写大量代码以确保内存安全并避免内存泄漏。 另一方面,Haskell,Python和Ruby等语言是安全的,但不允许进行低级控制,因此,基本上,这主要是在低级控制和安全性之间进行权衡。

现在,Rust诞生了,它基本上是C ++,具有更新的语法,可以指导程序员实现仍然允许低级控制的安全性,它是如何做到的? 所有权和借用之类的概念(我将在这个主题上写一个新博客)帮助其实现其他低级语言无法实现的内存安全性。

Malloc和垃圾收集器

在讨论所有权之前,我想谈谈诸如malloc和垃圾收集器之类的概念。诸如C和C ++之类的语言使用malloc在堆上分配内存,这为程序员提供了许多低级的内存管理控制,但是如果开发人员不够谨慎,则会导致许多错误,例如双重释放,悬空指针和内存泄漏。让我对这些问题进行一些解释,双重释放是一个问题,其中代码的两个部分都指向相同的内存块,并且它们都试图释放分配的内存。该部分之一成功释放了内存,但另一部分没有任何可用空间。当一个节释放内存,而另一个节指向同一块时,我们也可以用与上述相同的示例来说明另一个问题,即悬空指针。同样,即使我们以后不打算使用相同的内存块,也没有释放分配的内存块时,就会发生内存泄漏。

为了解决上述所有问题,Haskell,Python和Ruby之类的语言称为垃圾收集器。 垃圾收集器是编译器和解释器上的服务,该解释器可自动标识不再使用的内存位置并释放内存。 这是一个很好的概念,但是垃圾收集器需要一些时间来在运行时分析和清理内存,这可能会使我们的程序执行时间更长一些,因为需要暂停程序才能让垃圾收集器完成其工作。 由于语言本身负责分配和取消分配内存,因此低级内存管理不在窗口之列。

所有权

因此,如果Rust是安全的并且提供了许多低级内存控制,那么所有权是什么? 当Rust程序开始执行时,它将创建一个堆栈,该堆栈跟踪该程序上发生的所有事情。 首先,执行main方法,然后将其添加到堆栈中,在更专业的术语中,该堆栈称为调用堆栈。 让我们假设(将尽可能多的变量存储在寄存器中)然后将遇到的每个函数与变量一起添加到堆栈中,并在函数中定义值,从而创建一个作用域系统(只能访问堆栈中定义的所有内容) 在以下堆栈上)。 堆栈不能容纳大量数据,由于计算机上的堆栈受到限制,因此我们需要具有一定长度的数据(静态数据类型),因此我们倾向于在堆上存储较大的数据集(动态数据类型) 内存(也有限制,但大小比堆栈大得多),并在堆栈上添加指针引用(对堆位置的引用)。

当函数执行结束于各个变量时,存储在堆栈中的值将被丢弃,从而清理捕获的内存资源。这是Rust不需要垃圾收集器的原因之一。到目前为止,一切看起来都很不错,对吧?让我们举个例子,我们在向量(数据结构)上有大量数据,这些数据存储在堆中,并在堆栈上对其进行引用。假设一个函数现在想要将存储在向量(数据结构)上的数据集合复制到一个新的变量名,将整个数据集复制到另一个存储位置是否有效?糟糕,没有复制大量数据的做法效率低下,并且会占用大量内存空间。我们不复制实际数据,而是复制内存引用(指针),从而使代码更高效,更快速并节省大量内存空间。现在,我们创建了两个指向堆中相同内存位置的变量,这导致了我上面提到的问题,例如双释放指针和悬空指针。

在这种情况下,Rust将所有权定义为给定的一组数据结构,在任何时候,只有一个变量拥有该数据结构的所有权。 让我们尝试通过一个真实的例子来理解这一点,假设您已经购买了一本书,在这种情况下,您是该书的所有者,您除了自己之外就没有其他人拥有这本书。 如果有人想读这本书,那么他们就不会得到它的副本,如果他们愿意,那是另一本书。 阅读完毕后,您可以销毁这本书。 Rust上的数据结构也会发生同样的情况,在任何给定的时间实例中,只有一个堆栈帧可以拥有该数据结构,这具有很好的含义,因为一旦拥有它的堆栈帧出了,我们就可以安全地从堆中释放数据结构 的堆栈。 酷吧? 不再有悬空的指针。

但是在上述情况下存在问题,我们没有在重用书籍或资源。 如果您和您的朋友之一想要一本书,那么可以将其赠予您的朋友,而不是在阅读后销毁它。

同样的情况也可能在这里发生,例如,如果两个变量指向相同的数据结构该怎么办。 为此,Rust具有一个称为"移动"的概念。 就像在现实世界中的示例中,当某人想要阅读您的书时,他/她向您索要该书,因此您将所有权转让给他/她,而现在您不再有权使用该书,您已经转让了所有权,该书属于 你的朋友。 当两个变量指向相同的数据结构时,Rust上也会发生同样的事情。 仅当新变量超出范围时,所有权才移至新变量,然后才释放内存,从而解决了双重释放的问题。

得出结论,这是Rust不需要垃圾收集器的原因之一。 它使用堆栈来跟踪程序。 使用所有权Rust可以在释放内存的同时提供安全性。 当具有相应数据的各个变量在完全执行相应函数之后超出范围时,Rust释放内存。

在下一篇博客文章中,我将讨论借用Rust用来从函数管理指针返回类型的概念。 敬请关注。

感谢Achyut Pokhrel在发布之前检查内容。

(本文翻译自Rabin Gaire的文章《Memory Management & Rust》,参考:https://medium.com/@rabin_gaire/memory-management-rust-cf65c8465570)