回顾值类型 引用类型 string stringBuilder

公司的系统架构师问起了我String的值类型特性。说真的,我还差不多忘光了。

 趁着周末,总结了一下之前的理解。同时也结合了栈与堆的特点来分析:

  1   class Program

 2     {
 3         static void Main(string[] args)
 4         {
 5             //栈(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等
 6             //堆(head)— C++中由程序员分配释放,C#使用托管机制,交给GC回收。
 7             //值类型 在内存中的直接存储在栈中,而引用类型,如String str=new String("char"),new出的实例在堆中存放,并把存储地址引用给栈区中的str对象。
 8             //值类型,在赋值的时候把自己的副本附给了另外的变量
 9             //引用类型,在赋值的时候把堆的地址复制给另外的变量
10             int i = 2;
11             int j = i;
12             i = 5;
13             Console.WriteLine("i:{0} j:{1}",i,j);     
14             String hello = "Hello";
15             String test = hello;
16              hello = "Hi";
17              Console.WriteLine("hello:{0} test:{1} ",hello,test);
18             //在这个测试中,说明了String类型有值类型的特征。
19             //在堆中重新分一块内存空间给它放新的值而旧的依然存在,而不是覆盖原先的值是.原先的值将等着CG来回收。
20             //正因为如果大量的使用String 有可能影响到整个系统性能。
21             //那么栈直接由编译器处理,不需要GC 为什么不直接用栈 而还需要堆呢?
22             //原因在于栈是预留空间,堆是动态分配。
23             //如果你用 int [] i=int[1000],而实际上只用了其中的几个,那么不也是浪费吗!
24         }
25     }
 1 class StringAndStringBuilderDemo
 2     {
 3         static void Main(string[] args)
 4         {
 5             const int number=50000;
 6             long Time=Environment.TickCount;
 7             //String是不可变的,指它在堆上创建的内存空间里面的值不能被修改,而是通过创建新的空间。再返回该地址的引用。原来的空间在GC的时候回收。
 8             String str = null;
 9             for (int i = 0; i < number; i++)
10             {
11                 str += i.ToString();
12             }
13             Console.WriteLine("String:  {0} Mesl", Environment.TickCount - Time);
14 
15             Time = Environment.TickCount;
16             //StringBuilder 在创建的时候在堆中生成一片内存空间,如果空间足够就无需分配新的内部缓冲区数组。如果内部缓冲区溢出,则此容量自动增大
17             StringBuilder sb = new StringBuilder();
18             for (int i = 0; i < number; i++)
19             {
20                 sb.Append(i);
21             }
22             Console.WriteLine("StringBuilder:  {0} Msel", Environment.TickCount - Time);
23             string tmpStr1 = "A";
24             string tmpStr2 = tmpStr1;
25             Console.WriteLine(tmpStr1);
26             Console.WriteLine(tmpStr2);
27             tmpStr1 = "B";
28             Console.WriteLine(tmpStr1);
29             Console.WriteLine(tmpStr2);
30             //输出B A 证明 String 是在堆中创建了新的内存空间,并把其地址的引用赋予tmpStr1;
31             Console.ReadLine();
32         }
33     }

输出为: 

 String:  16500 Mesl

StringBuilder:  31 Msel
A
A
B
A
原文地址:https://www.cnblogs.com/xoray007/p/1959086.html