Go 围棋语言的概念记忆模型

Go 围棋语言的概念记忆模型,go,Go,我有个问题要问你们。我找不到关于Go记忆模型的详细信息。我将试着描述我的问题: 如果我在C语言中声明并定义一个变量或数组,我知道它存在于RAM中某个位置,有一个特定的地址,直到我做了一些改变它的事情 Python中不是这样的:Python为我管理整个内存,我不能确定我的数据是否总是位于一个位置。例如,字符串实际上是不可变的,即使语言表明它们不是。这使得使用敏感数据进行安全编程几乎不可能(或者至少非常不切实际) 我的问题是:从这个角度看,Go是如何工作的。它更像C还是Python?还是完全不同?是

我有个问题要问你们。我找不到关于Go记忆模型的详细信息。我将试着描述我的问题:

如果我在C语言中声明并定义一个变量或数组,我知道它存在于RAM中某个位置,有一个特定的地址,直到我做了一些改变它的事情

Python中不是这样的:Python为我管理整个内存,我不能确定我的数据是否总是位于一个位置。例如,字符串实际上是不可变的,即使语言表明它们不是。这使得使用敏感数据进行安全编程几乎不可能(或者至少非常不切实际)

我的问题是:从这个角度看,Go是如何工作的。它更像C还是Python?还是完全不同?是否可以像在C中一样轻松地处理敏感数据?

注意:如“”中所述:

[4]int
的内存表示形式只是四个按顺序排列的整数值:

Go的数组是值

数组变量表示整个数组它不是指向第一个数组元素的指针(与C中的情况相同)。这意味着当您分配或传递数组值时,您将复制其内容
(为了避免复制,您可以传递指向数组的指针,但那是指向数组的指针,而不是数组。)

考虑数组的一种方法是将其视为一种结构,但具有索引字段而不是命名字段:一个固定大小的复合值

如果您正在查看“指向数组的指针”,则需要一个切片

切片是数组段的描述符。它由指向数组的指针、段的长度及其容量(段的最大长度)组成

前面由
make([]字节,5)
创建的变量
s
,其结构如下:

有关阵列和片的内存分配工作方式,您可以查看“”

Go有两个分配原语,即内置函数
new
make

它们做不同的事情,适用于不同的类型,这可能会令人困惑,但规则很简单

  • 让我们先谈谈新的。它是一个分配内存的内置函数,但与其他一些语言中的同名函数不同,它不初始化内存,只将内存归零。
    也就是说,
    new(T)
    T
    类型的新项分配零存储,并返回其地址,即
    *T
    类型的值
    在Go术语中,它返回一个指针,指向新分配的
    T
    类型的零值

  • :内置函数
    make(T,args)
    的用途不同于
    new(T)
    。它仅创建切片、贴图和通道,并返回类型为
    T
    (非
    *T
    )的初始化(非归零)值。
    区别的原因是这三种类型在封面下表示对必须在使用前初始化的数据结构的引用
    例如,切片是一个三项描述符,包含指向数据(在数组中)、长度和容量的指针,在初始化这些项之前,切片为零


更多信息请参见“”。

在Go中处理内存的方式介于C和Python中的工作方式之间。Go比Python对内存布局的控制要多得多,大约和C一样多。但是Go是垃圾收集的,就像Python一样。因此,您无法明确控制内存的分配和释放

有时围棋中的记忆可以自动移动。当goroutine的堆栈满时,它将被复制到更大的堆栈。有朝一日,Go可能也会有一个类似Java的复制垃圾收集器。(现在没有。)

因此,确保敏感数据不会留在内存中可能比在C中更难。但在具有虚拟内存的系统(即所有现代计算机)中,始终存在这样的可能性,即您的进程将被交换,而其他进程将获得其内存。也许操作系统会先将内存归零,也许不会


但在Go中,将敏感值留在内存中并不像在C中那样危险。Go不允许您访问片边界之外的内存,就像C使用其数组一样。(这就是导致Heartbleed错误的原因。)当你在Go中分配一个新的内存块时,它会被归零,因此没有任何东西会以这种方式泄漏。

给self的注意:读起来也很好。如果你想手动清除内存,也就是说,在释放之前将其归零,我认为字符串是无法做到的(它们是不可变的)但您可以对其他类型(如数组、切片等)执行此操作。如果在释放字符串之前需要将字符串归零,最好使用[]字节。@grayfox,以扩展此答案。。。您可以按照Go中的既定做法,使用自定义类型(声明为像
type SecureBuffer[]byte
)上的
Erase()
方法,该方法将覆盖该片下数组的内容;然后,您记录下,一旦不再需要安全字符串,就必须对其调用
Erase()
。@grayfox,但请注意,将
SecureBuffer
强制转换为
string
将复制字节,
append()
-ing可能会重新分配涉及内存复制的内存。因此,这种方法的安全程度实际上取决于预期的安全级别。结果可能是更多涉及的计划即将出台。