元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
C#运行时环境
▶
CLR基础架构
CLR组成与生命周期
托管代码执行流程
应用程序域机制
▶
程序集体系
程序集元数据结构
强名称与版本控制
动态程序集生成
▶
类型系统
CTS核心规范
值类型与引用类型
类型加载与验证
▶
编译与执行
▶
编译过程
从源代码到IL
JIT编译原理
AOT编译机制
▶
执行引擎
方法表结构
栈帧与调用约定
尾调用优化
▶
IL深入解析
IL指令集解析
元数据表结构
调试符号处理
▶
内存管理
▶
垃圾回收
分代回收算法
终结器机制
GC句柄类型
▶
内存模型
托管堆结构
栈内存管理
大对象堆优化
▶
内存优化
内存碎片处理
ArrayPool机制
Span内存视图
发布时间:
2025-03-24 11:05
↑
☰
# GC句柄类型 ## 概述 GC句柄(GCHandle)是.NET中用于在托管堆和非托管代码之间建立引用关系的机制。本文将详细介绍不同类型的GC句柄、其使用场景以及性能影响。 ## GC句柄类型 ### 1. 基本类型 ```csharp public class GCHandleTypesExample { public void DemonstrateHandleTypes() { object obj = new object(); // 1. Normal句柄 var normal = GCHandle.Alloc(obj, GCHandleType.Normal); // 2. Weak句柄 var weak = GCHandle.Alloc(obj, GCHandleType.Weak); // 3. Pinned句柄 var pinned = GCHandle.Alloc(obj, GCHandleType.Pinned); // 4. WeakTrackResurrection句柄 var weakTrack = GCHandle.Alloc(obj, GCHandleType.WeakTrackResurrection); try { // 使用句柄 ProcessHandle(normal); } finally { // 释放句柄 if (normal.IsAllocated) normal.Free(); if (weak.IsAllocated) weak.Free(); if (pinned.IsAllocated) pinned.Free(); if (weakTrack.IsAllocated) weakTrack.Free(); } } private void ProcessHandle(GCHandle handle) { if (handle.IsAllocated) { object target = handle.Target; // 处理目标对象 } } } ``` ## 使用场景 ### 1. 固定对象 ```csharp public class PinnedObjectExample { public unsafe void ProcessArray() { byte[] data = new byte[1000]; // 固定数组 GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); try { // 获取固定地址 IntPtr ptr = handle.AddrOfPinnedObject(); // 使用指针处理数据 byte* p = (byte*)ptr.ToPointer(); for (int i = 0; i < data.Length; i++) { p[i] = (byte)(i % 256); } } finally { // 释放固定句柄 handle.Free(); } } } ``` ### 2. 弱引用实现 ```csharp public class WeakReferenceExample { private class CacheItem { public string Data { get; set; } } public void ImplementCache() { // 创建缓存项 var item = new CacheItem { Data = "缓存数据" }; // 创建弱引用 var weakHandle = GCHandle.Alloc(item, GCHandleType.Weak); try { // 检查对象是否存活 if (weakHandle.Target != null) { var cachedItem = weakHandle.Target as CacheItem; Console.WriteLine($"缓存数据: {cachedItem.Data}"); } else { Console.WriteLine("缓存项已被回收"); } } finally { // 释放句柄 if (weakHandle.IsAllocated) weakHandle.Free(); } } } ``` ### 3. 跨边界通信 ```csharp public class InteropExample { public void DemonstrateInterop() { // 创建托管对象 var managedObject = new ComplexObject(); // 分配Normal句柄 var handle = GCHandle.Alloc(managedObject); try { // 转换为IntPtr IntPtr ptr = GCHandle.ToIntPtr(handle); // 传递给非托管代码 PassToNative(ptr); // 从IntPtr恢复对象 var restored = GCHandle.FromIntPtr(ptr).Target as ComplexObject; } finally { // 释放句柄 handle.Free(); } } private void PassToNative(IntPtr ptr) { // 模拟非托管代码处理 var handle = GCHandle.FromIntPtr(ptr); var obj = handle.Target; // 处理对象 } private class ComplexObject { public string Name { get; set; } public int Value { get; set; } } } ``` ## 性能优化 ### 1. 句柄管理 ```csharp public class HandleManagementExample { public class HandleManager : IDisposable { private List<GCHandle> handles = new List<GCHandle>(); public IntPtr AllocateHandle(object obj, GCHandleType type) { var handle = GCHandle.Alloc(obj, type); handles.Add(handle); return GCHandle.ToIntPtr(handle); } public void ReleaseHandle(IntPtr ptr) { var handle = GCHandle.FromIntPtr(ptr); if (handles.Contains(handle)) { handle.Free(); handles.Remove(handle); } } public void Dispose() { foreach (var handle in handles) { if (handle.IsAllocated) handle.Free(); } handles.Clear(); } } } ``` ### 2. 性能考虑 ```csharp public class PerformanceConsiderationsExample { public void OptimizeHandleUsage() { // 1. 句柄池化 var handlePool = new Stack<GCHandle>(); // 2. 批量处理 var handles = new List<GCHandle>(); try { for (int i = 0; i < 100; i++) { var obj = new object(); handles.Add(GCHandle.Alloc(obj)); } // 批量处理句柄 ProcessHandles(handles); } finally { // 批量释放 foreach (var handle in handles) { if (handle.IsAllocated) handle.Free(); } } } private void ProcessHandles(List<GCHandle> handles) { foreach (var handle in handles) { if (handle.IsAllocated) { // 处理句柄 } } } } ``` ## 最佳实践 ### 1. 安全使用 ```csharp public class SafeHandleExample { public class SafeHandleWrapper : IDisposable { private GCHandle handle; private bool disposed = false; public SafeHandleWrapper(object target, GCHandleType type) { handle = GCHandle.Alloc(target, type); } public IntPtr Handle { get { if (disposed) throw new ObjectDisposedException(nameof(SafeHandleWrapper)); return GCHandle.ToIntPtr(handle); } } public void Dispose() { if (!disposed) { if (handle.IsAllocated) handle.Free(); disposed = true; } } ~SafeHandleWrapper() { Dispose(); } } } ``` ### 2. 错误处理 ```csharp public class ErrorHandlingExample { public void HandleErrors() { GCHandle handle = default; try { // 分配句柄 handle = GCHandle.Alloc(new object()); // 验证句柄 if (!handle.IsAllocated) throw new InvalidOperationException("句柄分配失败"); // 使用句柄 ProcessHandle(handle); } catch (Exception ex) { Console.WriteLine($"处理句柄时出错: {ex.Message}"); throw; } finally { // 安全释放 if (handle.IsAllocated) handle.Free(); } } private void ProcessHandle(GCHandle handle) { try { var target = handle.Target; if (target == null) throw new InvalidOperationException("目标对象已被回收"); // 处理目标对象 } catch (InvalidOperationException) { // 处理特定错误 throw; } } } ``` ## 总结 GC句柄是.NET中的重要机制,它提供了: 1. 类型多样性 - Normal句柄 - Weak句柄 - Pinned句柄 - WeakTrackResurrection句柄 2. 功能特性 - 对象固定 - 弱引用支持 - 跨边界通信 - 内存管理 3. 使用准则 - 及时释放 - 异常处理 - 性能优化 - 安全使用 通过合理使用GC句柄,我们可以: - 优化内存管理 - 提高互操作性 - 实现高级功能 - 保证代码安全