C#---引用类型,值类型和堆栈
2021-06-21 10:04
标签:运行 eric short bool thread 清理 isp 垃圾回收器 stack 1.值类型(System.ValueType类)和栈(Stack) System.ValueType--bool、byte、char、decimal、double、enum、float、int、long、sbyte、short、struct、unit、ulong、ushort。 栈是编译期间就分配好的内存空间,代码中就栈的大小有明确的定义。栈是连续的内存域,由系统自动分配和维护。 A->B->C->D 函数调用压栈 返回是弹栈D->C->B->A 值类型不一定被分配到栈上,值类型被声明在一个方法体外并且在一个引用类型中,会在堆上进行分配。(成员变量或属性) 栈内存无需我们管理,也不受GC管理。栈顶元素使用完毕,立即释放。 2.引用类型(System.Object)和堆(Heap) System.Object---class、interface、delegate、object、string 堆是程序运行期间动态分配的内存空间,可以根据程序的运行情况确定要分配的堆内存大小。堆是无序的,由用户来控制和释放,若用户不释放,当内存达到一定的特定值时,通过垃圾回收器(GC)回收。 堆则需要GC(Garbage collection:垃圾收集器)清理 在程序运行的时候,每个线程(Thread)都会维护一个自己的专属线程堆栈。 指针: 当一个方法被调用的时候,主线程开始在所属程序集的元数据中,查找被调用方法,然后通过JIT即时编译并把结果(一般是本地CPU指令)放在栈顶。CPU通过总线从栈顶取指令,驱动程序以执行下去。 3. 栈示例: 方法开始调用时,方法参数在栈上分配 方法内部开始执行时,变量result被分配在栈上 方法执行完毕,而且方法返回后 栈上的区域被清理。 4.堆示例 方法被调用时,参数被分配到栈上 方法开始执行,由于MyInt是引用类型,result是指向引用类型的指针 方法执行完毕,栈上内存被清理,但堆中依然存在 当程序需要更多的堆空间时,GC需要进行垃圾清理工作,暂停所有线程,找出所有不可达到对象,即无被引用的对象,进行清理。并通知栈中的指针重新指向地址排序后的对象。当我们使用引用类型的时候,一般是对指针进行的操作而非引用类型对象本身。但是值类型则操作其本身。 5.Dictionary 值类型: IL代码: 引用类型: IL代码: C#---引用类型,值类型和堆栈 标签:运行 eric short bool thread 清理 isp 垃圾回收器 stack 原文地址:https://www.cnblogs.com/mbaymax/p/10237337.html
public int AddFive(int pValue)
{
int result;
result = pValue + 5;
return result;
}
public class MyInt
{
public int MyValue;
}
public MyInt AddFive(int pValue)
{
MyInt result = new MyInt();
result.MyValue = pValue + 5;
return result;
}
Dictionarystring, int> doc = new Dictionarystring, int>();
doc.Add("sl", 1);
doc.Add("xm", 2);
doc.Add("xl", 3);
foreach (var item in doc)
{
Console.WriteLine(item.Value);
}
.method public hidebysig static void TestValueType() cil managed
{
// 代码大小 106 (0x6a)
.maxstack 3
.locals init ([0] class [mscorlib]System.Collections.Generic.Dictionary`2string,int32> doc,
[1] valuetype [mscorlib]System.Collections.Generic.Dictionary`2/Enumeratorstring,int32> V_1,
[2] valuetype [mscorlib]System.Collections.Generic.KeyValuePair`2string,int32> item)
IL_0000: nop
IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.Dictionary`2string,int32>::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldstr "sl"
IL_000d: ldc.i4.1
IL_000e: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2string,int32>::Add(!0,
!1)
IL_0013: nop
IL_0014: ldloc.0
IL_0015: ldstr "xm"
IL_001a: ldc.i4.2
IL_001b: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2string,int32>::Add(!0,
!1)
IL_0020: nop
IL_0021: ldloc.0
IL_0022: ldstr "xl"
IL_0027: ldc.i4.3
IL_0028: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2string,int32>::Add(!0,
!1)
IL_002d: nop
IL_002e: nop
IL_002f: ldloc.0
IL_0030: callvirt instance valuetype [mscorlib]System.Collections.Generic.Dictionary`2/Enumerator0,!1> class [mscorlib]System.Collections.Generic.Dictionary`2string,int32>::GetEnumerator()
IL_0035: stloc.1
.try
{
IL_0036: br.s IL_004f
IL_0038: ldloca.s V_1
IL_003a: call instance valuetype [mscorlib]System.Collections.Generic.KeyValuePair`20,!1> valuetype [mscorlib]System.Collections.Generic.Dictionary`2/Enumeratorstring,int32>::get_Current()
IL_003f: stloc.2
IL_0040: nop
IL_0041: ldloca.s item
IL_0043: call instance !1 valuetype [mscorlib]System.Collections.Generic.KeyValuePair`2string,int32>::get_Value()
IL_0048: call void [mscorlib]System.Console::WriteLine(int32)
IL_004d: nop
IL_004e: nop
IL_004f: ldloca.s V_1
IL_0051: call instance bool valuetype [mscorlib]System.Collections.Generic.Dictionary`2/Enumeratorstring,int32>::MoveNext()
IL_0056: brtrue.s IL_0038
IL_0058: leave.s IL_0069
} // end .try
finally
{
IL_005a: ldloca.s V_1
IL_005c: constrained. valuetype [mscorlib]System.Collections.Generic.Dictionary`2/Enumeratorstring,int32>
IL_0062: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0067: nop
IL_0068: endfinally
} // end handler
IL_0069: ret
} // end of method Program::TestValueType
Dictionarystring, Student> doc = new Dictionarystring, Student>();
Student s = new Student();
s.name = "sl";
s.point = 1;
doc.Add("NO1",s);
Student t = new Student();
t.name = "xm";
s.point = 2;
doc.Add("NO2", t);
Student st = new Student();
st.name = "xl";
st.point = 3;
doc.Add("NO3", st);
foreach(var item in doc)
{
item.Value.name = "same";
}
.method public hidebysig static void TestObject() cil managed
{
// 代码大小 184 (0xb8)
.maxstack 3
.locals init ([0] class [mscorlib]System.Collections.Generic.Dictionary`2string,class TestDictionaryIL.Program/Student> doc,
[1] class TestDictionaryIL.Program/Student s,
[2] class TestDictionaryIL.Program/Student t,
[3] class TestDictionaryIL.Program/Student st,
[4] valuetype [mscorlib]System.Collections.Generic.Dictionary`2/Enumeratorstring,class TestDictionaryIL.Program/Student> V_4,
[5] valuetype [mscorlib]System.Collections.Generic.KeyValuePair`2string,class TestDictionaryIL.Program/Student> item)
IL_0000: nop
IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.Dictionary`2string,class TestDictionaryIL.Program/Student>::.ctor()
IL_0006: stloc.0
IL_0007: newobj instance void TestDictionaryIL.Program/Student::.ctor()
IL_000c: stloc.1
IL_000d: ldloc.1
IL_000e: ldstr "sl"
IL_0013: stfld string TestDictionaryIL.Program/Student::name
IL_0018: ldloc.1
IL_0019: ldc.i4.1
IL_001a: stfld int32 TestDictionaryIL.Program/Student::point
IL_001f: ldloc.0
IL_0020: ldstr "NO1"
IL_0025: ldloc.1
IL_0026: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2string,class TestDictionaryIL.Program/Student>::Add(!0,
!1)
IL_002b: nop
IL_002c: newobj instance void TestDictionaryIL.Program/Student::.ctor()
IL_0031: stloc.2
IL_0032: ldloc.2
IL_0033: ldstr "xm"
IL_0038: stfld string TestDictionaryIL.Program/Student::name
IL_003d: ldloc.1
IL_003e: ldc.i4.2
IL_003f: stfld int32 TestDictionaryIL.Program/Student::point
IL_0044: ldloc.0
IL_0045: ldstr "NO2"
IL_004a: ldloc.2
IL_004b: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2string,class TestDictionaryIL.Program/Student>::Add(!0,
!1)
IL_0050: nop
IL_0051: newobj instance void TestDictionaryIL.Program/Student::.ctor()
IL_0056: stloc.3
IL_0057: ldloc.3
IL_0058: ldstr "xl"
IL_005d: stfld string TestDictionaryIL.Program/Student::name
IL_0062: ldloc.3
IL_0063: ldc.i4.3
IL_0064: stfld int32 TestDictionaryIL.Program/Student::point
IL_0069: ldloc.0
IL_006a: ldstr "NO3"
IL_006f: ldloc.3
IL_0070: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2string,class TestDictionaryIL.Program/Student>::Add(!0,
!1)
IL_0075: nop
IL_0076: nop
IL_0077: ldloc.0
IL_0078: callvirt instance valuetype [mscorlib]System.Collections.Generic.Dictionary`2/Enumerator0,!1> class [mscorlib]System.Collections.Generic.Dictionary`2string,class TestDictionaryIL.Program/Student>::GetEnumerator()
IL_007d: stloc.s V_4
.try
{
IL_007f: br.s IL_009d
IL_0081: ldloca.s V_4
IL_0083: call instance valuetype [mscorlib]System.Collections.Generic.KeyValuePair`20,!1> valuetype [mscorlib]System.Collections.Generic.Dictionary`2/Enumeratorstring,class TestDictionaryIL.Program/Student>::get_Current()
IL_0088: stloc.s item
IL_008a: nop
IL_008b: ldloca.s item
IL_008d: call instance !1 valuetype [mscorlib]System.Collections.Generic.KeyValuePair`2string,class TestDictionaryIL.Program/Student>::get_Value()
IL_0092: ldstr "same"
IL_0097: stfld string TestDictionaryIL.Program/Student::name
IL_009c: nop
IL_009d: ldloca.s V_4
IL_009f: call instance bool valuetype [mscorlib]System.Collections.Generic.Dictionary`2/Enumeratorstring,class TestDictionaryIL.Program/Student>::MoveNext()
IL_00a4: brtrue.s IL_0081
IL_00a6: leave.s IL_00b7
} // end .try
finally
{
IL_00a8: ldloca.s V_4
IL_00aa: constrained. valuetype [mscorlib]System.Collections.Generic.Dictionary`2/Enumeratorstring,class TestDictionaryIL.Program/Student>
IL_00b0: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_00b5: nop
IL_00b6: endfinally
} // end handler
IL_00b7: ret
} // end of method Program::TestObject
上一篇:Geth RPC API中文文档
下一篇:WPF 流加载