面试题答案
一键面试1. 栈和堆上的存储方式
- 指针:
- 存储位置:指针变量本身存储在栈上,它保存的是另一个变量在内存中的地址。例如,在C# 中使用
unsafe
代码定义指针int* ptr;
,ptr
这个指针变量存于栈,它指向的实际int
型数据存储位置不定,取决于具体分配情况。 - 访问方式:通过指针直接操作内存地址来访问所指向的数据。如
*ptr
表示访问指针ptr
所指向的内存位置的值。
- 存储位置:指针变量本身存储在栈上,它保存的是另一个变量在内存中的地址。例如,在C# 中使用
- 引用类型:
- 存储位置:引用类型的变量本身存储在栈上,而其实际的数据内容存储在堆上。例如
string str = "Hello";
,str
这个引用存于栈,而实际的字符串“Hello”存于堆。 - 访问方式:通过栈上的引用找到堆上的数据进行访问。如对
str
操作,实际是通过栈上的引用找到堆上字符串数据操作。
- 存储位置:引用类型的变量本身存储在栈上,而其实际的数据内容存储在堆上。例如
2. 垃圾回收机制对它们的影响
- 指针:
- 手动管理:在C# 中使用指针时处于
unsafe
上下文,垃圾回收器不会自动管理指针指向的内存。开发人员需要手动负责分配和释放内存,否则容易造成内存泄漏。例如使用Marshal.AllocHGlobal
分配非托管内存后,需调用Marshal.FreeHGlobal
释放。 - 与GC关系:指针操作可能干扰垃圾回收器正常工作,因为垃圾回收器基于特定算法移动和整理堆内存,指针可能指向已被移动或回收的内存区域,引发错误。
- 手动管理:在C# 中使用指针时处于
- 引用类型:
- 自动管理:垃圾回收器负责管理引用类型在堆上分配的内存。当一个引用类型对象不再被任何变量引用(即没有可达路径),垃圾回收器会在适当时候回收该对象占用的内存。例如
string str = "Hello"; str = null;
,当str
设为null
后,原“Hello”字符串对象若没有其他引用,垃圾回收器会回收其内存。 - 标记清除算法:垃圾回收器采用标记 - 清除等算法,首先标记所有可达对象,然后清除未标记(不可达)对象占用的内存空间,完成对引用类型内存的自动回收。
- 自动管理:垃圾回收器负责管理引用类型在堆上分配的内存。当一个引用类型对象不再被任何变量引用(即没有可达路径),垃圾回收器会在适当时候回收该对象占用的内存。例如