上一篇分享了.Net面试八股文,很多小伙伴求答案。限于篇幅和时间,本篇说一下前25个问题的答案。
声明下,这些问题你可能在一些AI上能够得到答案。但是请注意了,AI回答这种问题,似是而非,有非常大的错误和误导。
这里作者通过多年研究CLR/JIT源码得出的结论(如有疏漏,可不吝指正),给予参考:
1 .Net GC回收步骤 答案:标记,计划,重定位,压缩,清扫
2 .跨代对象引用是什么 答案:不同代之间的对象引用,比如二代对象引用了短暂堆对象
3 .字符串存储在哪个堆 答案:.Net7在GC堆,.Net8在GC堆外
4 .根对象是什么,以及如何释放它 答案:局部引用变量,一般有编译器释放。
5 .固定对象的含义 答案:非托管对象的句柄,在GC堆不会被GC移动
6 .解释下,强引用句柄,弱引用句柄 答案:强引用句柄指示的对象不可回收,弱引用句柄的对象可以被回收
7 .析构函数是如何运行的 答案:通过内核对象进行通知调用析构函数线程,取出析构列表堆(FinalizerListSeg)或者是关键析构列表堆里面包含析构函数的对象,运行析构函数。
8 .GC何时启用升代 答案:执行2代GC回收的时候
9 .GC计划阶段的二叉树是如何构建的 答案:主要通过奇偶数来确定二叉树顶点和叶子节点构建
10.GC是如何标记对象存活的 答案:通过JIT编译GCInfo保存根对象,GC的时候取出根对象递归标记
11.GC如何重新决定目标代 答案:阈值用完或者需要低延迟的时候
12.执行GC的线程有几种 答案:三种,后台线程,工作站线程,服务器线程
13.GC总体流程 答案:停止其它线程,确定回收目标代,(标记,计划,重定位,压缩,清扫),结束
14.分配了阈值的计算 答案:通过系数,碎片率进行计算,非常复杂,公式以后有时间列出
15.分配小对象和大对象的区别在哪儿 答案:分配空间大小的大不同,以85000字节为界限
16.new关键字是如何分配对象的 答案:通过分配上下文或者是通过API来分配,分为快速和慢速
17.分代实现的过程 答案:每个CPU核分为四个代,三个小对象代(0,1,2),一个大对象代(2)
18.托管堆,堆段,区域,分配上下文,都是什么 答案:分别为存储分配的对象,CPU核的内存的划分,CPU核的内存,指向分配对象的指针
19.函数的内存模型 答案:主要五个,分别为
MethodTable,MethodDesc,PreCode,Fixup,MethodDesChunk
20.AOT的编译流程 答案:通过ILC把源码编译成目标文件,通过llvm后端链接目标文件,生成目标机器可执行文件
21.ILC是什么 答案:AOT编译器
21.存活标记和固定标记保存在哪里,在哪些位标记上 答案:保存在MT(类型信息)上,分别在分为在其最后一位和高三位上
22.类型信息(MT),对象头(ObjHeader),它们的作用 答案:MT主要是区分是哪个对象,Objheader主要是用于线程同步等作用
23.堆空间与栈空间的区别 答案:堆需要手动释放,栈则编译器自动释放
24.延迟模式,GC模式,保留堆段空间地址是怎么优化GC的 答案:主要是通过CLR的GC机制进行优化的,环境变量可以控制其是否优化
25.JIT的IR是什么 答案:中间表象,主要是JIT的MSIL和机器码之间的那一层代码