C# 如何存储字符串

本文关键字:存储 字符串 何存储 | 更新日期: 2023-09-27 17:56:41

我想了解像"Hello World"这样的字符串值的存储位置或方式。

例如:

示例 1:

radLabel1.Text = "Hello";
radLabel2.Text = "Hello";
radLabel3.Text = "Hello";

示例 2:

string strTemp = "Hello";
radLabel1.Text = strTemp;
radLabel2.Text = strTemp;
radLabel3.Text = strTemp;

我知道第二种方式最有用,我这样做,但我想知道示例 1 的字符串是如何存储在 RAM 中的。我想虽然它们是相同的,但在RAM中为它们创建了三个位置来存储它们。但在示例 2 中,只为示例 2 的字符串创建了一个位置,并使用此地址进行访问。 我说的对吗?你能解释一下或将变量存储在 RAM 中吗?

C# 如何存储字符串

通常流传的

术语是字符串文字被"拘留"。 这是一个毫无意义的术语,并没有很好地描述到底发生了什么。

.NET 程序集包含两个数据块,即元数据和 IL。 元数据主要用于描述程序集中的类型,并包含资源。 IL 是您编写的代码,已转换为中间语言格式。

元数据部分有 5 个表,其中一个称为"字符串表"。 高度描述它所包含的内容,这就是存储"Hello"字符串的位置。 它的格式已经与字符串通常存储在垃圾回收堆中的方式相同,但在对象标头中有一个额外的标志,指示它是一个字符串文本,而不是存储在堆中。

程序集内容通过内存映射文件映射到虚拟内存中,该文件与 .NET System.IO.MemoryMappedFiles.MemoryMapFile 类完全相同。 strTemp 对象引用将由抖动发出的单个 MOV 指令初始化,并存储一个指针,该指针直接指向文件的映射视图中的字符串表条目。 程序首次实际使用字符串内容时,操作系统页面错误可确保字符串将存在于 RAM 中。

垃圾回收器将在执行收集时找到 strTemp 对象引用。 但只会忽略引用,对象标头中的标志说它应该,因为字符串对象实际上并没有存储在垃圾回收堆中。 这才是"实习"的真正含义。

我想虽然它们是一样的,但三个地方是为 它们在 RAM 中存储它们。

字符串被扣留

当它们是相同的字符串常量时,只维护一个副本。这意味着在您的第一个示例中只有一个"Hello"。

在示例 2 中,您将在第一行上创建单个字符串。然后,您只需将对它的引用传递给这 3 个标签。正如你所说,它仍然是内存中的单个对象。但是,由于字符串在 C# 中是不可变的,因此将新字符串分配给 radLabel2.Text 不会更改其他字符串的值,而是会创建一个新字符串。

当您声明时

   radLabel1.Text="Hello";

它将一个带有值 Hello 的临时字符串创建到内存中的某个位置,并将该值传递给 radLabel.text 。对于radLabel2.Text和radLabel3.text,程序会创建temp 2和temp 3来存储"Hello"。Beause没有什么可以告诉程序它们是相同的。

但是,当您声明时

   string strTemp = "Hello";

它在内存中创建一个字符串(当然),但与"Hello"不同。因为他们为它创造了一个名字。这就像计算机的桌面快捷方式一样工作。因此,当您使用它时,您只是调用了快捷方式,并且它绕过了创建新字符串的进度,因为该值已经定义。

希望你明白