# 构造函数：
概念：
实例化时，用于初始化的函数
不写默认有一个无参构造函数
==可以重载==

通常用法：
自定义初始化规则

语法：
访问修饰符 类名(){}

案例：
```Csharp
class Person()
{
	public string name;
	public int age;
	public Person()
	{
		name = "默认值";
		age = 默认值;
	}
}
```

this关键字：
	this指当前类声明的成员变量
```Csharp
	class Person()
	{
		public string name;
		public int age;
		public Person()
		{
			name = "默认值";
			age = 默认值;
		}
		public Person(int age,string name) //重构
		{
			this.name = name;
			//后面的name是传递的参数，this.name是最上方public int出来的
			this.age = name;
		}
	}
```

特殊写法：
	通过this重用构造函数代码,即先调用无参构造函数，然后在调用这个特殊写法的构造函数
	语法：访问修饰符 构造函数名（参数列表）：this（【可选】参数1，参数2.....）
	例子：
```Csharp
		public Person(int age, string name)：this（age）
		{
			balabala
		}
```
		过程：先调用无参Person构造函数，然后寻找只有构造单个参数age的构造函数进行初始化
	
注意：
==函数名和类名必须相同==
==没有特殊用途，一般都是public==

==如果写了有参构造函数且自己没有保留无参构造函数，那么类在实例化时只能使用有参构造函数且无法使用无参构造函数==



----
# 析构函数
概念：
当引用类型堆内存被回收时，会调用该函数
对于需要手动管理内存的语言（C++），需要在析构函数中做一些内存回收处理
C#有自动垃圾回收机制GC
Unity中基本不用管

通常用法：


语法：
```Csharp
~类名（）
{
}
```
案例：
```Csharp
~Person（）
{

}
```

注意：


----
# 垃圾回收
垃圾回收（GC）
通过遍历堆Heap上动态分配的所有对象
通过识别他们是否被引用来确定哪些对象时垃圾，哪些对象仍然需要引用
垃圾：没有变量或对象引用的内容
如果是垃圾就要被回收释放

一般都是==被动触发（会造成卡顿）==，所以游戏一般需要手动执行垃圾回收
语法：GC.Collect();
==GC会造成卡顿，所以在加载Loading时一般会调用==

垃圾回收有多种算法
引用计数
标记清楚
标记整理
复制集合

注意：
GC只负责Heap内存的垃圾祸首
引用类型都是在Heap中的，所以他需要GC来进行管理

栈Stack上的内存时系统自动管理的
所以不需要GC

C#中垃圾回收机制的大概原理
他会把内存分为0，1，2代内存
代的概念是垃圾回收中的一种算法需要
新分配的对象都会被配置在第0代内存中
每次分配都可能会进行垃圾回收（一般来说0代内存满了就会触发）
在第一次内存回收过程开始时，垃圾回收器会认为堆中全是垃圾，会进行一下两部
1.标记对象，从根（静态参数、方法参数）开始检查引用对象，标记后为可达对象，未标记就是不可大对象
不可达对象就会认为是垃圾
2.搬迁对象 压缩堆 （挂起执行内存托管代码线程：把第0代内存（还不是垃圾的内存）放到一代进行搬迁）释放未标记的对象、搬迁可达对象、修改引用地址 

大对象总被认为是二带内存，目的是减少性能损耗
不会对大对象进行压缩搬迁 大对象是85000kb以上的

示意图
step1:程序放入内存
![[Pasted image 20260412210327.png|697]]
step2:发现沾满了
![[Pasted image 20260412210704.png]]
step3:原来的地址搬迁，无引用的垃圾丢掉
![[Pasted image 20260412210810.png]]
step4:D放入
![[Pasted image 20260412210946.png]]
step5:如果0代1代后续又满了，那么这套算法会同时做用在两代内存中，以此类推
类似多级缓存cache，L1最快但常换L3最慢
<<<<<<< ours
#基础
=======
#基础
>>>>>>> theirs
