字符串创建

Num*_*nif 4 .net c# string

我在循环中有一个关于字符串创建的问题,下面是一个代码示例:

 static void Main(string[] args)
    {

        for (int i = 1; i <= 1000000; i++)
        {
            Add(GetStr());
        }

        Console.WriteLine("hmmmmmmmm");
        Console.ReadLine();
    }

    public static string GetStr()
    {
        return "OK";            
    }

    public static void Add(string str)
    {
        list.Add(str);
    }
Run Code Online (Sandbox Code Playgroud)

如果上面的代码,将在内存中创建多少个字符串???

Mår*_*röm 9

在上述代码的情况下,将在内存中创建多少个字符串

一.(如果包括,实际上是两个"hmmmmmmmm")

此方法返回一个常量字符串文字:

public static string GetStr()
{
    return "OK";            
}
Run Code Online (Sandbox Code Playgroud)

它编译成类似下面的IL代码:

ldstr "OK"
ret
Run Code Online (Sandbox Code Playgroud)

LDSTR操作码将会推到一个字符串文字的引用存储在元数据RET操作码将返回引用.

这意味着"OK"只会在元数据中分配一次.列表中的所有条目都将引用该实例.

请注意,默认情况下会对字符串文字进行实习.因此在被实习之前不会分配"临时字符串",因此不需要垃圾回收.

  • @RoyaanKhan:好的.那么你强制系统每次动态分配一个新的字符串.`"OK"`仍然是对存储在元数据中的字符串的引用.但是,`UTF.GetString(bytes)`将在每次调用时分配一个新的字符串实例. (2认同)

Bas*_*ili 5

我修改了你的代码,以便你可以看到字符串"OK"的Memory addrese

using System;

namespace ConsoleApplication4
{
  using System.Collections.ObjectModel;

  public class Program
  {
    static unsafe Collection<string> list = new Collection<string>();

    static unsafe void Main(string[] args)
    {
      for (int i = 1; i <= 10; i++)
      {
        Add(GetStr());
      }

      foreach (var str in list)
      {
        fixed (char* ptr = str)
        {
          var addr = (IntPtr)ptr;
          Console.WriteLine(addr.ToString("x"));
        }
      }

      Console.WriteLine("hmmmmmmmm");
      Console.ReadLine();
    }

    public unsafe static string GetStr()
    {
      return "OK";
    }

    public unsafe static void Add(string str)
    {
      list.Add(str);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

------------控制台输出------------------------

如您所见,列表对字符串"Ok"使用相同的内存引用.

#225bf54
#225bf54
#225bf54
#225bf54
#225bf54
#225bf54
#225bf54
#225bf54
#225bf54
#225bf54
hmmmmmmmm
Run Code Online (Sandbox Code Playgroud)