zoukankan      html  css  js  c++  java
  • 回顾值类型 引用类型 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
  • 相关阅读:
    em与rem之间的区别以及移动设备中的rem适配方案
    关于两个DIV之间的空白字符
    Bootstrap基本模板
    js 裁剪
    记一次诡异的bug
    Node切换版本
    git 撤销
    使用 iframe + postMessage 实现跨域通信
    <el-input>标签限制输入小数点
    vue elementyUI table :点击一行时选中这一行对应的复选框
  • 原文地址:https://www.cnblogs.com/xoray007/p/1959086.html
Copyright © 2011-2022 走看看