值类型与引用类型-004好汉
问题:
- 什么是值类型,什么是引用类型;
- 值类型与引用类型的区别;
- 为什么要分值类型与引用类型;
解答:
第一部分:
- 值类型就是变量名就是变量的值;存于栈中;引用类型则是变量名在栈中保存一个内存地址指向堆中真实数据值;
- 值类型有: 结构类(数据类型,bool,用户自定义结据,杖举,可空类型。
- 引用类型有:自定义类,接口,
第二部分:
- 主要是数据内存分配方式的不同,一种是栈一种是堆;
- 以上两图是简单描述;
- int a = 3;int b = 4;a = b;拷贝方式是将b内存值,拷贝给a内存;这种赋值;
- class jia{public int a;} class jia j = new jia{a = 1;b=2;}; class b = j; 这种也是赋值;其实与值类型赋值一样,修改了变量栈中的内存值;使得j与b在栈中的值是一样的,因此指向的堆中位置是一样,使得j与b共享一块内存;修改堆中的值,都受影响;
- 由于引用类型的出现,出现了浅拷贝与深拷贝两种;主要区别在于堆中内存引用类型的值不同,一种是地址,一种是真实数据值;
- 浅拷贝:要继承ICloneable ,待补充
- 深拷贝:待补充;
- 值类型与引用类型内存回收方式不同,一种是系统自动回收,一种是垃圾机制回收;
- 引用类型类对象实例内存分配方式:
- 在对象实例中,在堆中会分成三部分,第一部分对象头字节(同步索引块),第二部分为函数表指针,第三部分为实例数据;简单来说:class jia{public int a ;}; jia j = new jia(a =2);实例中堆分配的内存大小为12字节,j指向第二部分起始地址;
- 一、二部分用于JIT与CLR;
- 同步索引块在锁对象起作用,当lock对象时,系统会查询对象同步索引中的值,看是否被其它线程占用,不是,就从全局的索引数组中分配一值,表明被线程占用。直到lock完成;
如单例代码测试:
public class Singleton{private static Singleton _instance = null;private static object obj = new object();public static Singleton Instance{get {lock (obj) {Thread.Sleep(10000);if(_instance == null) return _instance = new Singleton();}return _instance;}}}class Program{static void Main(string[] args){DateTime d1 = DateTime.Now;Thread t = new Thread(test);t.Start();Singleton ss = Singleton.Instance;Console.WriteLine("main thread");Console.WriteLine("time{0}", DateTime.Now - d1);}static void test(){Singleton s = Singleton.Instance;Console.WriteLine("other thread");}}从代码可以看出,主线程要等,线程t释放singleton,才得到singleton实例;
第三部分:
- 待补充;
ps:待各位指出不足与更深入部分