Csharp
1.c#gc的触发条件有哪些,如何避免频繁gc,如何手动控制gc
触发条件:
对象的物理内存较低
托管堆上分配的对象占用的内存超出了可接受阈值
调用
GC.Collect()方法
如何避免频繁 GC :
对于频繁出现消失的物体使用对象池管理
减少
new产生对象的次数使用公用的对象,即静态成员
Static,但要谨慎使用(例如一个List<int>含有大量的数据却没有清除一直占用着内存)如果是在
unity当中,尽量避免使用foreach,尽量使用for
Unity 当中为什么要尽量避免使用 foreach : foreach 内部有迭代器,会导致装箱操作,进而引起频繁的 GC.Alloc ,尤其是在 Update 当中调用其之后会造成大量的小块垃圾内存,造成垃圾回收操作的提前到来,造成游戏间歇性的卡顿。
如何手动控制 gc : 使用 GC.Collect() 方法,可以传入一个 0 , 1, 2 三个数字,以清除第几代的托管堆内存
2.什么是异步,为什么要使用异步编程,异步与多线程的关系,task和thread的区别,Unity的协程和Task的区别
什么是异步: 异步是一种编程模型,其允许程序在执行某个操作的时候不需要等待其完成,而是可以执行其他的任务。在异步编程中,程序的执行是非阻塞的。
为什么要使用异步编程: 当使用一些耗时的操作时,如 I/O,或者网络请求,此时同步运行就会阻塞掉我们的程序,导致在等待这个操作完成之前程序都无法响应外部的操作。而使用异步编程时则不会被阻塞。
异步与多线程的关系:
异步就是彼此独立,在等待某事件的过程中继续做自己的事,不需要等待这一事件完成后再工作。
多线程是程序设计的逻辑层概念,它是进程中并发运行的一段代码。多线程可以实现线程间的切换执行。
多线程就是实现异步的一个方式。异步是让调用方法的主线程不需要同步等待另一线程的完成,从而可以让主线程干其它的事情。
Task 和 Thread 的区别:
Task可以有返回值,而Thread没有返回值在使用
Thread时,如果我们在长时间运行的方法中获得异常,则不可能在父函数中捕获该异常,但是如果我们在使用Task,则很容易捕获该异常。Task可取消任务执行,Thread不行Task是基于Thread的,会使用底层的线程池。Task默认使用后台线程执行,Thread默认使用前台线程
Unity 协程和 Task 的区别:
Unity协程实际上是IEnumrator的可迭代函数,通过StartCoroutine方法将其注册进MonoBehaviour的协程管理器,而Task是可以使用async/await还有Task.Run来创建异步任务协程是基于单线程的,在每一帧当中插入操作。
Task是基于线程池的yield return不能存在于任何try-catch代码块中,故协程也不能捕获异常,而Task可以捕获异常
3.委托的本质是什么,c#委托的底层实现思路是什么,委托和委托实例和事件三者的关系,为什么要使用委托
委托的本质: 委托就是一个密封类,其对象维护着一个可以引用一个或多个方法的字段
c# 委托的底层实现思路是什么: 底层通过一个密封类,其里面封装了一个 IntPtr 类型的指针,也就是个函数指针,可以引用方法。然后通过一个 object? 来维护调用此方法的对象(静态方法为 null )
委托和委托实例和事件三者的关系:
委托是一个密封类,委托的对象中维护着一个字段,其指向程序中另一个或多个以后会被调用的方法,可以使用
delegate关键字声明一个委托类型,指定方法的参数和返回值类型。委托实例是委托类型的实例化对象,它引用一个或多个方法。
事件是一种特殊的委托,在委托实例化时的时候加上
event关键字,声明一个事件。其必须配合一个类来使用。
为什么要使用委托: 可以将方法作为另一个方法的参数来进行传递,这张方法动态地赋给参数的做法,可以避免在程序中大量使用if-else ,Switch 语句,同时使得程序具有更好的可扩展性
4.值类型和引用类型的基类分别是什么
引用类型的基类是 Object ,值类型的基类是 ValueType ,值类型也隐式继承自 Object
5.
Last updated