string易错点整理总结

 

 

 

简单说 string  就是char[],本质是一个16位Unicode字符数组,在托管堆,不在GC堆

 

string 和System.String

string 是C#语言的基元类型,类似于int,long等等,简化了语言代码,带来便捷可读性,System.String是FCL的基本类型,和有直接的映射关系,从IL角度看,两者之间没有任何不同

 

恒定性:

 

 

 字符串驻留:

公共语言运行库 通过维护一个表来存放字符串,该表称为驻留池,它包含 程序中 以编程方式声明或创建的

每个唯一的字符串的一个引用,因此特定的值的字符串的实例在系统中只有一个,如果将同一字符串分配给

几个变量,运行库会从驻留池中检索到该字符串的相同引用,并将它分配给各个变量

 

 

 

 

  有个易搞错的是  Isinterned返回 非null, 不代表两个字符串 引用了相同的内存地址,如下:

 还是上面所说的,在string s3=s3+"c"时   s3 的变量的值是动态拼接生成的,并没有直接去哈希表中拿到来实现,所以是不同的内存地址

关于 IsInterned的:

   例子来了,它有助于让我们了解string的存储方面的东西:

① 最一般的

② 动态加后,会是什么呢

③再复杂些

 即

       

④ 但是如果后面 还有个语句,就有意思了,如下:

⑤ 如果不是变量,而是方法呢

 ⑥ 如果是常量呢

 ⑦ 如果是静态字段呢

 

 ⑧但是如果是两个字符串 显示拼接,编译器是会合并的,可以在IL代码中看到

下面就不难理解

 

 ⑨ 

 

 

 

 string 和StringBuilder

 

 

 

 

 

关于两者的比较:

一:String类

  说到String类,资料上都说是存在于堆上的一个不可CURD的一个不可变的字符集,当然看到这句话之后就想要看看是不是这样的,然后就

好奇的写了以下代码。

复制代码
1     class Program
2     {
3         static void Main(string[] args)
4         {
5             string s = "123";
6         }
7     }
复制代码

 

从上面的IL中也就仅仅发现一个ldstr指令,看得出clr把string做成了基元类型,也就没看到它具体转换成了什么样的方法,是不是调用了string

的构造函数,这个也不清楚,也就不知道具体怎么把这个有序字符集放到堆中,不过办法还是有的,我们随便挑一个方法看看,比如简单一点的

substring,我们看看它的源代码。

 

 

然后我们找到了一个核心的方法,这个internalSubstring里面定义了两个指针ptr和ptr2,ptr则指向新申请的内存块的首地址,ptr2则指向原始

字符串的首地址,最后将ptr2的位置偏移startindex个位置,最后我们就找到了终极方法string.wstrcpy。

 

在string.wstrcpy方法里面,虽然看的迷迷糊糊,不过还是能看到类似这样的偏移操作,一点一点的将smem地址上的字符赋值给dmem中,

确实也就说明了在堆上是有序的字符集。

 

 

同样在上面的源代码中来说,substring操作并没有对原始字符串进行修改,而是把截取的值放到新申请的内存地址空间中,这也就说明了字符

串是不可修改的说法,当然如果设计者真的要做到原位修改,那肯定也是能做到的,为了佐证下,我再举一个经常用到的concat方法,不过在

FastAllocateString方法中,并没有看到他的源代码,所以只能说根据length申请合适的空间。

 

所以结论出来了: 当你对字符串进行大量操作的时候,会产生很多的新的字符串,这些字符串会大量零碎的占据着堆空间,大多都是生存期较短

        的,所以一般都是在堆的第一代上,所以会对gc产生了比较大回收压力。

 

二:StringBuilder

   看这个类的话,还是看一下它的源代码,就抽一个Append吧,从下面这个截图中看出来几个有意思的地方。

<1> 原来StringBuilder里面维护的是一个m_ChunkChars的字符数组。

<2> 如果当前的字符串的length<2,会直接给chunkchars数组复制,length>2的时候看到的是刚才string类中经典的wstrcpy用法,而

      这个时候ptr指向的是chunkChars[chunkLength]的首地址,而不像string中申请新的内存空间,所以从这里看,比string大大的节省

    了内存空间。

 

posted @ 2020-09-24 01:33  凯帝农垦  阅读(152)  评论(0编辑  收藏  举报