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
  • 相关阅读:
    Net设计模式实例之简单工厂模式(Simple Factory Pattern)
    Net设计模式实例系列文章总结
    2019年工作总结
    在Asp.Net Core中集成Kafka(中)
    如何将生产环境的服务Docker镜像拉取到本地进行调试
    记一次EFCore类型转换错误及解决方案
    Asp.Net Core中创建多DbContext并迁移到数据库
    ABP中的AutoMapper
    EFCore中的导航属性
    Asp.Net Core 调用第三方Open API查询物流数据
  • 原文地址:https://www.cnblogs.com/xoray007/p/1959086.html
Copyright © 2011-2022 走看看