




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第C#中的引用類型以及特殊引用類型詳解引用類型分配在哪里
引用類型變量位于線程棧。引用類型實例分配在托管堆上。當(dāng)引用類型實例的大小小于85000bytes,被分配在GC堆上,當(dāng)大于或等于85000bytes,被分配在LOH(LargeObjectHeap)上。
變量(Variable),對象(Object),實例(Instance)
變量:
變量分配在線程棧上。
變量可以是值類型,也可以是引用類型。
當(dāng)變量是引用類型時,包含了對對象的引用(內(nèi)存地址),也叫做對象引用。
對象:
對類、接口、委托和數(shù)組等的一個抽象描述。
實例:
在堆上創(chuàng)建的對象,稱為對象實例。
引用類型沒有new意味著什么?
Objecta=null;
Console.WriteLine(a.ToString());
運(yùn)行報錯未將對象引用設(shè)置到對象實例。
意思是,在線程棧上創(chuàng)建的變量a沒有指向到堆上的對象實例。
托管堆上的垃圾回收
GC會遍歷所有托管堆上的對象,按照一定的遞歸遍歷算法,對那些沒有被引用的不可訪問對象實施回收。
new的背后發(fā)生了什么
classProgram
staticvoidMain(string[]args)
Personp;
p=newPerson(20);
publicclassPerson
publicint_age;
publicPerson(intage)
_age=age;
publicPerson()
}
另外,引用類型的值,比如這里的引用類型Person中的值_age也被分配在托管堆上。
線程棧上的2個變量引用同一個對象實例的內(nèi)存地址
線程棧上的2個變量引用同一個對象實例的內(nèi)存地址,改變其中一個變量的值會影響到另外一個變量。
classProgram
staticvoidMain(string[]args)
Personp1=newPerson(20);
Personp2=p1;
Console.WriteLine("沒有改變時p2的年齡是:"+p2._age+"歲");
p1._age=18;
Console.WriteLine("改變p1的值,p2的年齡也被改變了,現(xiàn)在是:"+p2._age+"歲,真好,年輕了!");
Console.ReadKey();
publicclassPerson
publicint_age;
publicPerson(intage)
_age=age;
publicPerson()
}
string類型是特殊的引用類型
特殊性體現(xiàn)在
從應(yīng)用角度體現(xiàn)了值類型語義,從內(nèi)存角度實現(xiàn)為引用類型存儲,位于托管堆。
什么是string
可以看作是char的集合char[]
string創(chuàng)建與實例化
stringstr=Hello
以下錯誤
Stringstr=newString(Hello
因為System.String沒有提供此構(gòu)造函數(shù)
以下可以
Char[]cs={a,b,c
StringstrArr=newString(cs);
但很少使用這種方式。
字符串的恒定性Immutability
是指字符串一經(jīng)創(chuàng)建,就不可改變。
字符串一旦創(chuàng)建,在托管堆上分配一塊連續(xù)的內(nèi)存空間。
恒定性的好處:
對String對象的任意操作,不會改變原字符串。
操作字符串不會出現(xiàn)線程同步的問題。
成就了字符串駐留。
恒定性的不足:
因為恒定性,對字符串的任何操作,比如字符串比較,字符串鏈接,字符串格式化等都會創(chuàng)建新的字符串,這樣造成內(nèi)存與性能的雙重?fù)p耗。如下:
publicstaticvoidMain()
stringstr="Thisisatestaboutimmuntablilityofstringtype.";
Console.WriteLine(str.Inseert(0,"Hi").Substring(19).ToUpper());
Console.WriteLine(str);
}
由于Insert,Substring,ToUpper這些方法,都會創(chuàng)建出新的臨時字符串,而這些新的字符串不被其他代碼引用的時候,就會被垃圾回收,造成性能上的損失。
恒定性的前提,String為密封類:
publicsealedclassString:IComparable,ICloneable,IConvertible,IComparablestring,IEnumerablechar,IEnumerable,IEquatablestring
字符串駐留StringInterning
MSDN對于字符駐留的定義:公共語言運(yùn)行庫通過維護(hù)一個哈希表(HashTable)來存放字符串,該表成為拘留池,也叫駐留池。
字符串駐留彌補(bǔ)了恒定性的不足:
對于相同的字符串,CLR不會不會為其分配內(nèi)存空間,而是共享同一內(nèi)存。
CLR內(nèi)部維護(hù)了一個哈希表HashTable來管理其創(chuàng)建的大部分String對象。key是string本身,value是string對應(yīng)的內(nèi)存地址。
駐留的2個靜態(tài)方法:
publicstaticstringIntern(stringstr);
當(dāng)str位于作為key位于CLR的駐留池時,返回對str的引用,否則將str字符串添加到hashtable中,作為key,并返回引用。
publicstaticstringIsInterned(stringstr);
當(dāng)str位于作為key位于CLR的駐留池時,返回對str的引用,否則返回null引用,也不添加到hashtable中。
字符串駐留是進(jìn)程級的
可以跨應(yīng)用程序域AppDomain而存在,駐留池在CLR加載時創(chuàng)建,分配在SystemDomain中,被進(jìn)程所有AppDomain所共享,其生命周期不受GC控制。
staticvoidMain(string[]args)
stringstrA="ab";
stringstrB="ab";
Console.WriteLine(ReferenceEquals(strA,strB));
stringstrC="a";
stringstrD=strC+"b";
Console.WriteLine(ReferenceEquals(strA,strD));
strD=String.Intern(strD);
Console.WriteLine(ReferenceEquals(strA,strD));
Console.ReadKey();
}
返回:
true
false
true
分析:
strA與strB內(nèi)容相同,在hashtable中的key相同,對應(yīng)了一樣的引用地址,所以返回true。strD的內(nèi)容雖然與strA相同,但由于是動態(tài)生成的,不會把hashtable中key為ab的引用地址賦值給strD,所以strA與strD引用地址不一樣,返回false。strD=String.Intern(strD);手動對strD實施駐留,并發(fā)現(xiàn)hashtable中已經(jīng)有了ab這個key,就把對應(yīng)的引用地址賦值給了strD,這樣,strA與strD引用地址相同,返回true。
staticvoidMain(string[]args)
strings1="abc";
strings2="ab";
strings3=s2+"c";
Console.WriteLine(string.IsInterned(s3)"null");
Console.WriteLine(ReferenceEquals(s1,s3));
Console.ReadKey();
}
返回:
abc
false
分析:
string.IsInterned(s3)對s3進(jìn)行手動駐留,發(fā)現(xiàn)hashtable中abc這個key,于是,就返回abc的引用地址。但并沒有把引用地址賦值給s3。s1和s3的引用地址還是不一樣,返回false。
staticvoidMain(string[]args)
stringstrA="abcdef";
stringstrC="abc";
stringstrD=strC+"def";
Console.WriteLine(ReferenceEquals(strA,strD));
stringStrE="abc"+"def";
Console.WriteLine(ReferenceEquals(strA,StrE));
Console.ReadKey();
}
返回:
False,
true
分析:
因為strD=strC+def中strD的內(nèi)容雖然與strA想同,但因為是動態(tài)生成的,不會被添加到hashtable中,所以引用地址不一樣,返回false。abc+def在IL中呈現(xiàn)為abcdef,不是動態(tài)生成的,并且發(fā)現(xiàn)hashtable中已經(jīng)有了abcdef這個key,于是就把對應(yīng)的引用地址賦值給了strE,這樣strA和StrE就有了相同的引用地址,返回true。如圖:
staticvoidMain(string[]args)
strings="abc";
//IsInterned()獲取字符串變量的引用
Console.WriteLine(string.IsInterned(s)"null");
Console.ReadKey();
}
返回
abc。
分析:通過strings=abc使得hashtable中有abc這個key,當(dāng)進(jìn)行string.IsInterned(s)手動駐留判斷的時候,發(fā)現(xiàn)有abc這個key,就把對應(yīng)的引用地址返回。
classProgram
staticvoidMain(string[]args)
strings="ab";
s+="c";
//IsInterned()獲取字符串變量的引用
Console.WriteLine(string.IsInterned(s)"null");
Con
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年震擺式篩砂機(jī)項目市場調(diào)查研究報告
- 2025年工藝?yán)C珠相框項目市場調(diào)查研究報告
- 磺胺獸用藥品企業(yè)ESG實踐與創(chuàng)新戰(zhàn)略研究報告
- 智能溫控戶外服裝品牌企業(yè)制定與實施新質(zhì)生產(chǎn)力戰(zhàn)略研究報告
- 智能手寫筆跡識別筆記本行業(yè)跨境出海戰(zhàn)略研究報告
- 瑪卡增強(qiáng)體力酒企業(yè)制定與實施新質(zhì)生產(chǎn)力戰(zhàn)略研究報告
- 游艇租賃管理平臺行業(yè)深度調(diào)研及發(fā)展戰(zhàn)略咨詢報告
- 智能電子溫控系統(tǒng)行業(yè)深度調(diào)研及發(fā)展戰(zhàn)略咨詢報告
- 復(fù)方胰蛋白酶膠囊企業(yè)縣域市場拓展與下沉戰(zhàn)略研究報告
- 智能安全系統(tǒng)企業(yè)制定與實施新質(zhì)生產(chǎn)力戰(zhàn)略研究報告
- 2024年陜西高中學(xué)業(yè)水平合格性考試生物試卷真題(含答案)
- 國家職業(yè)技術(shù)技能標(biāo)準(zhǔn) 6-31-01-03 電工 人社廳發(fā)2018145號
- 2024《整治形式主義為基層減負(fù)若干規(guī)定》全文課件
- 中考數(shù)學(xué)二元一次方程專題訓(xùn)練100題(含答案)
- 野外生存優(yōu)秀課件
- 10t單梁起重機(jī)安裝方案
- 箱庭療法-沙盤游戲治療技術(shù)課件
- YY∕T 0953-2020 醫(yī)用羧甲基殼聚糖(高清正版)
- 建筑承包工程中業(yè)主指定分包與承包商內(nèi)部分包的區(qū)別
- 小學(xué)生電力科普小講座PPT課件
- 井下工具之一封隔器ppt
評論
0/150
提交評論