色尼玛亚洲综合影院,亚洲3atv精品一区二区三区,麻豆freexxxx性91精品,欧美在线91

深入理解string和如何高效地使用string

  一個(gè)月以前我寫了一篇討論字符串的駐留(string interning)的文章,我今天將會(huì)以字符串的駐留為基礎(chǔ),進(jìn)一步來(lái)討論.NET中的string。string interning的基本前提是string的恒定性(immutability),即string一旦被創(chuàng)建將不會(huì)改變。我們就先來(lái)談?wù)剆tring的恒定性。

  一、string是恒定的(immutable)

  和其他類型比較,string最為顯著的一個(gè)特點(diǎn)就是它具有恒定不變性:我們一旦創(chuàng)建了一個(gè)string,在managed heap 上為他分配了一塊連續(xù)的內(nèi)存空間,我們將不能以任何方式對(duì)這個(gè)string進(jìn)行修改使之變長(zhǎng)、變短、改變格式。所有對(duì)這個(gè)string進(jìn)行各項(xiàng)操作(比如調(diào)用ToUpper獲得大寫格式的string)而返回的string,實(shí)際上另一個(gè)重新創(chuàng)建的string,其本身并不會(huì)產(chǎn)生任何變化。

  String的恒定性具有很多的好處,它首先保證了對(duì)于一個(gè)既定string的任意操作不會(huì)造成對(duì)其的改變,同時(shí)還意味著我們不用考慮操作string時(shí)候出現(xiàn)的線程同步的問(wèn)題。在string恒定的這些好處之中,我覺(jué)得最大的好處是:它成就了字符串的駐留。

  CLR通過(guò)一個(gè)內(nèi)部的interning table保證了CLR只維護(hù)具有不同字符序列的string,任何具有相同字符序列的string所引用的均為同一個(gè)string對(duì)象,同一段為該string配分的內(nèi)存快。字符串的駐留極大地較低了程序執(zhí)行對(duì)內(nèi)存的占用。

  對(duì)于string的恒定性和字符串的駐留,還有一點(diǎn)需要特別指出的是:string的恒定性不單單是針對(duì)某一個(gè)單獨(dú)的AppDomain,而是針對(duì)一個(gè)進(jìn)程的。

  二、String可以跨AppDomain共享的(cross-appDomain)

  我們知道,在一個(gè)托管的環(huán)境下,Appdomain是托管程序運(yùn)行的一個(gè)基本單元。AppDomain為托管程序提供了良好的隔離機(jī)制,保證在同一個(gè)進(jìn)程中的不同的Appdomain不可以共享相同的內(nèi)存空間。在一個(gè)Appdomain創(chuàng)建的對(duì)象不能被另一個(gè)Appdomain直接使用,對(duì)象在AppDomain之間傳遞需要有一個(gè)Marshaling的過(guò)程:對(duì)象需要通過(guò)by reference或者by value的方式從一個(gè)Appdomain傳遞到另一個(gè)Appdomain。具體內(nèi)容可以參照我的另一篇文章:用Coding證明Appdomain的隔離性

  但是這里有一個(gè)特例,那就是string。Appdomain的隔離機(jī)制是為了防止一個(gè)Application的對(duì)內(nèi)存空間的操作對(duì)另一個(gè)Application 內(nèi)存空間的破壞。通過(guò)前面的介紹,我們已經(jīng)知道了string是恒定不變的、是只讀的。所以它根本不需要Appdomain的隔離機(jī)制。所以讓一個(gè)恒定的、只讀的string被同處于一個(gè)進(jìn)程的各個(gè)Application共享是沒(méi)有任何問(wèn)題的。

String的這種跨AppDomain的恒定性成就了基于進(jìn)程的字符串駐留:一個(gè)進(jìn)程中各個(gè)Application使用的具有相同字符序列的string都是對(duì)同一段內(nèi)存的引用。我們將在下面通過(guò)一個(gè)Sample來(lái)證明這一點(diǎn)。

  三、證明string垮AppDomain的恒定性

  在寫這篇文章的時(shí)候,我對(duì)如何證明string跨AppDomain的interning,想了好幾天,直到我偶然地想到了為實(shí)現(xiàn)線程同步的lock機(jī)制。

  我們知道在一個(gè)多線程的環(huán)境下,為了避免并發(fā)操作導(dǎo)致的數(shù)據(jù)的不一致性,我們需要對(duì)一個(gè)對(duì)象加鎖來(lái)阻止該對(duì)象被另一個(gè)線程 操作。相反地,為了證明兩個(gè)對(duì)象是否引用的同一個(gè)對(duì)象,我們只需要在兩個(gè)線程中分別對(duì)他們加鎖,如果程序執(zhí)行的效果和對(duì)同一個(gè)對(duì)象加鎖的情況完全一樣的話,那么就可以證明這兩個(gè)被加鎖的對(duì)象是同一個(gè)對(duì)象。基于這樣的原理我們來(lái)看看我們的Sample:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace Artech.ImmutableString
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            AppDomain appDomain1 
= AppDomain.CreateDomain("Artech.AppDomain1");
            AppDomain appDomain2 
= AppDomain.CreateDomain("Artech.AppDomain2");

            MarshalByRefType marshalByRefObj1 
= appDomain1.CreateInstanceAndUnwrap(
"Artech.ImmutableString""Artech.ImmutableString.MarshalByRefType"as MarshalByRefType;
            MarshalByRefType marshalByRefObj2 
= appDomain2.CreateInstanceAndUnwrap(
"
Artech.ImmutableString""Artech.ImmutableString.MarshalByRefType"as MarshalByRefType;

            marshalByRefObj1.StringLockHelper 
= "Hello World";
            marshalByRefObj2.StringLockHelper 
= "Hello World";

            Thread thread1 
= new Thread(new ParameterizedThreadStart(Execute));
            Thread thread2 
= new Thread(new ParameterizedThreadStart(Execute));

            thread1.Start(marshalByRefObj1);
            thread2.Start(marshalByRefObj2);

            Console.Read();            
        }


        
static void Execute(object obj)
        

            MarshalByRefType marshalByRefObj 
= obj as MarshalByRefType;
            marshalByRefObj.ExecuteWithStringLocked();
        }

    }


    
class MarshalByRefType : MarshalByRefObject
    
{
        
Private Fields

        
Public Properties

        
Public Methods
    }

}

NET技術(shù)深入理解string和如何高效地使用string,轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 江永县| 申扎县| 无为县| 察哈| 平乡县| 商城县| 台北县| 巍山| 宁阳县| 荆门市| 东乌珠穆沁旗| 浦江县| 万载县| 锡林郭勒盟| 信阳市| 息烽县| 垦利县| 泰来县| 远安县| 阜新市| 柘荣县| 福贡县| 沙坪坝区| 喀喇沁旗| 察隅县| 扎鲁特旗| 静安区| 固阳县| 仙居县| 金乡县| 曲沃县| 四川省| 汶上县| 寿宁县| 三河市| 榆林市| 陆丰市| 呈贡县| 无为县| 开封市| 昌乐县|