




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第C#中的引用类型以及特殊引用类型详解引用类型分配在哪里
引用类型变量位于线程栈。引用类型实例分配在托管堆上。当引用类型实例的大小小于85000bytes,被分配在GC堆上,当大于或等于85000bytes,被分配在LOH(LargeObjectHeap)上。
变量(Variable),对象(Object),实例(Instance)
变量:
变量分配在线程栈上。
变量可以是值类型,也可以是引用类型。
当变量是引用类型时,包含了对对象的引用(内存地址),也叫做对象引用。
对象:
对类、接口、委托和数组等的一个抽象描述。
实例:
在堆上创建的对象,称为对象实例。
引用类型没有new意味着什么?
Objecta=null;
Console.WriteLine(a.ToString());
运行报错未将对象引用设置到对象实例。
意思是,在线程栈上创建的变量a没有指向到堆上的对象实例。
托管堆上的垃圾回收
GC会遍历所有托管堆上的对象,按照一定的递归遍历算法,对那些没有被引用的不可访问对象实施回收。
new的背后发生了什么
classProgram
staticvoidMain(string[]args)
Personp;
p=newPerson(20);
publicclassPerson
publicint_age;
publicPerson(intage)
_age=age;
publicPerson()
}
另外,引用类型的值,比如这里的引用类型Person中的值_age也被分配在托管堆上。
线程栈上的2个变量引用同一个对象实例的内存地址
线程栈上的2个变量引用同一个对象实例的内存地址,改变其中一个变量的值会影响到另外一个变量。
classProgram
staticvoidMain(string[]args)
Personp1=newPerson(20);
Personp2=p1;
Console.WriteLine("没有改变时p2的年龄是:"+p2._age+"岁");
p1._age=18;
Console.WriteLine("改变p1的值,p2的年龄也被改变了,现在是:"+p2._age+"岁,真好,年轻了!");
Console.ReadKey();
publicclassPerson
publicint_age;
publicPerson(intage)
_age=age;
publicPerson()
}
string类型是特殊的引用类型
特殊性体现在
从应用角度体现了值类型语义,从内存角度实现为引用类型存储,位于托管堆。
什么是string
可以看作是char的集合char[]
string创建与实例化
stringstr=Hello
以下错误
Stringstr=newString(Hello
因为System.String没有提供此构造函数
以下可以
Char[]cs={a,b,c
StringstrArr=newString(cs);
但很少使用这种方式。
字符串的恒定性Immutability
是指字符串一经创建,就不可改变。
字符串一旦创建,在托管堆上分配一块连续的内存空间。
恒定性的好处:
对String对象的任意操作,不会改变原字符串。
操作字符串不会出现线程同步的问题。
成就了字符串驻留。
恒定性的不足:
因为恒定性,对字符串的任何操作,比如字符串比较,字符串链接,字符串格式化等都会创建新的字符串,这样造成内存与性能的双重损耗。如下:
publicstaticvoidMain()
stringstr="Thisisatestaboutimmuntablilityofstringtype.";
Console.WriteLine(str.Inseert(0,"Hi").Substring(19).ToUpper());
Console.WriteLine(str);
}
由于Insert,Substring,ToUpper这些方法,都会创建出新的临时字符串,而这些新的字符串不被其他代码引用的时候,就会被垃圾回收,造成性能上的损失。
恒定性的前提,String为密封类:
publicsealedclassString:IComparable,ICloneable,IConvertible,IComparablestring,IEnumerablechar,IEnumerable,IEquatablestring
字符串驻留StringInterning
MSDN对于字符驻留的定义:公共语言运行库通过维护一个哈希表(HashTable)来存放字符串,该表成为拘留池,也叫驻留池。
字符串驻留弥补了恒定性的不足:
对于相同的字符串,CLR不会不会为其分配内存空间,而是共享同一内存。
CLR内部维护了一个哈希表HashTable来管理其创建的大部分String对象。key是string本身,value是string对应的内存地址。
驻留的2个静态方法:
publicstaticstringIntern(stringstr);
当str位于作为key位于CLR的驻留池时,返回对str的引用,否则将str字符串添加到hashtable中,作为key,并返回引用。
publicstaticstringIsInterned(stringstr);
当str位于作为key位于CLR的驻留池时,返回对str的引用,否则返回null引用,也不添加到hashtable中。
字符串驻留是进程级的
可以跨应用程序域AppDomain而存在,驻留池在CLR加载时创建,分配在SystemDomain中,被进程所有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内容相同,在hashtable中的key相同,对应了一样的引用地址,所以返回true。strD的内容虽然与strA相同,但由于是动态生成的,不会把hashtable中key为ab的引用地址赋值给strD,所以strA与strD引用地址不一样,返回false。strD=String.Intern(strD);手动对strD实施驻留,并发现hashtable中已经有了ab这个key,就把对应的引用地址赋值给了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进行手动驻留,发现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的内容虽然与strA想同,但因为是动态生成的,不会被添加到hashtable中,所以引用地址不一样,返回false。abc+def在IL中呈现为abcdef,不是动态生成的,并且发现hashtable中已经有了abcdef这个key,于是就把对应的引用地址赋值给了strE,这样strA和StrE就有了相同的引用地址,返回true。如图:
staticvoidMain(string[]args)
strings="abc";
//IsInterned()获取字符串变量的引用
Console.WriteLine(string.IsInterned(s)"null");
Console.ReadKey();
}
返回
abc。
分析:通过strings=abc使得hashtable中有abc这个key,当进行string.IsInterned(s)手动驻留判断的时候,发现有abc这个key,就把对应的引用地址返回。
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. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 光伏板采购合同范例
- 产品贸易合同范例
- 住房资金合同范例
- 临时增项合同范例
- 公路养护技术咨询合同范例
- 全程托管养殖合同范例
- 中英采购合同范例
- 公路界桩预制合同范例
- 中俄海鲜供货合同范例
- GB团队游合同范例
- 《电缆状态监测》课件
- 青梅绿茶测试题及答案
- GA 1812.2-2024银行系统反恐怖防范要求第2部分:数据中心
- 2025至2030中国智慧消防行业发展状况及未来前景研究报告
- 联锁系统设备调试施工作业指导书
- 热网工程施工组织设计方案
- 乡村振兴智慧农业项目计划书
- 2025年上半年黑龙江牡丹江市“市委书记进校园”活动暨“雪城优才”企事业单位人才招聘1324人重点基础提升(共500题)附带答案详解
- 2025年重庆市中考物理模拟试卷(一)(含解析)
- 髌骨骨折的中医护理查房
- 希尔顿管理制度
评论
0/150
提交评论