在 .NET Core 环境中,内存管理是如何运作的?你会采取哪些措施来防止内存泄漏?
考察说明
考查对 .NET Core 内存管理机制(GC、托管堆、非托管资源)的理解及实际预防泄漏的能力。
回答思路
- 【回答框架 1】.NET Core 使用垃圾回收器(GC)进行托管内存管理,基于代龄(Gen0、Gen1、Gen2)和根引用追踪。对象分配在第 0 代堆上,GC 通过标记-压缩算法回收不可达对象,并提升存活对象。
- 【回答框架 2】避免内存泄漏的关键是管理非托管资源。实现 IDisposable 接口,在 Dispose 方法中释放非托管资源(如文件句柄、数据库连接),并通过 using 语句确保调用。
- 【回答框架 3】避免静态引用和事件处理器导致的意外引用。静态字段持有对象引用会使对象无法被回收,事件订阅后未取消订阅会导致被订阅的对象一直存活。
- 【回答框架 4】注意大对象堆(LOH)的碎片化和长期存活的大对象。LOH 默认不压缩,频繁分配大对象可能导致内存碎片,可考虑对象池化或压缩诱导。
- 【回答框架 5】使用内存分析工具(如 dotnet-counters、PerfView)监测内存使用,定位泄漏源,并实施定期审查和压力测试。
- 【关键点 1】GC 管理托管内存,分代回收提高效率。
- 【关键点 2】非托管资源需显式释放,实现 IDisposable 并通过 using 调用。
- 【关键点 3】避免静态引用和事件处理器未取消订阅。
- 【关键点 4】大对象堆碎片化是潜在问题。
- 【关键点 5】使用内存分析工具诊断内存问题。
- 【易错点 1】不要认为实现 IDisposable 就能自动回收内存,必须调用 Dispose 或使用 using。
- 【易错点 2】不要试图强制 GC.Collect 来优化内存,可能降低性能。
- 【易错点 3】小心匿名方法或 lambda 捕获外部对象,导致意外引用。