news 2026/7/2 2:22:54

告别频繁 GC:C#.NET PooledList 的设计与使用场景

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
告别频繁 GC:C#.NET PooledList 的设计与使用场景

简介

PooledList<T>是 高性能集合类型,由Collections.Pooled提供,用于替代List<T>,通过 对象池 (ArrayPool<T>) 复用内部数组来减少GC(垃圾回收)压力。

⚡ 核心目标:
在需要频繁创建/销毁List<T>的场景下,PooledList<T>通过数组租借与归还的机制避免频繁分配内存,从而提升性能并降低GC负担。

安装

dotnetaddpackage Collections.Pooled --version1.0.82

添加命名空间

usingCollections.Pooled;

特点

  • 数组池化:内部数组从ArrayPool<T>.Shared(默认)或自定义池中租借,减少分配。

  • Span<T>支持:提供Span属性,直接访问内部数组的填充部分,支持零拷贝操作。

  • IDisposable实现:调用Dispose()时,返回内部数组到池中(不调用Dispose不会出错,但会降低池化效果)。

  • 扩展方法:如TryFindTryFindLast(替换标准FindFindLast,返回bool以避免异常)。

  • 添加/插入SpanAddSpanInsertSpan方法返回一个Span<T>,允许直接写入内部存储,而无需多次调用Add

  • 构造函数选项:

    • 支持指定自定义ArrayPool<T>

    • clearMode参数控制数组返回池时是否清除内容(默认自动)。

    • sizeToCapacity参数使初始Count == Capacity,适合值类型避免不必要的零初始化。

  • ToPooledList()扩展:从IEnumerable<T>快速创建PooledList<T>

  • 性能提升:在高频操作中,减少GC触发,尤其适合循环中创建临时列表的场景。

内部原理

普通List<T>内部
  • List<T>内部维护一个T[]数组。

  • 当容量不足时会 申请更大数组 并 拷贝数据。

  • 对象销毁后,这些数组最终交给GC回收。

PooledList<T>内部
  • 内部数组不是直接new出来的,而是从ArrayPool<T>.Shared租借。

  • 使用结束时通过Dispose()方法 归还数组,供下次复用。

  • 避免频繁分配和回收大数组,降低GC Gen2压力。

基本用法

创建与释放
usingMicrosoft.Toolkit.HighPerformance.Buffers;usingvarlist=newPooledList<int>();// 自动使用 ArrayPool<int>list.Add(1);list.Add(2);list.Add(3);foreach(variteminlist){Console.WriteLine(item);}// Dispose() 会自动归还数组

💡 推荐使用 using 确保 Dispose() 被调用,否则不会归还数组,造成内存浪费。

初始容量
usingvarlist=newPooledList<int>(initialCapacity:1024);
转换为Span<T>/Memory<T>

PooledList<T>的优势之一是可以直接获取底层内存:

Span<int>span=list.AsSpan();Memory<int>memory=list.AsMemory();

这样可以高效地与Span/Memory API交互,避免额外拷贝。

常用操作

List<T>基本一致:

list.Add(10);list.AddRange(new[]{20,30,40});list.Insert(1,15);list.RemoveAt(0);list.Clear();Console.WriteLine(list.Count);Console.WriteLine(list.Capacity);

List<T>对比

特性List<T>PooledList<T>
内存分配每次扩容new新数组ArrayPool<T>租借,复用数组
GC 压力大量频繁创建/销毁时 GC 压力大减少 GC Gen2 压力
释放方式依赖 GC必须Dispose()归还数组
性能(频繁操作场景)可能产生大量堆分配高性能、低分配
Span/Memory 支持需要AsSpan()扩展内置AsSpanAsMemory,零拷贝访问
适用场景通用集合高性能、临时性数据集合(网络、序列化、算法)

高级用法

ArrayPool<T>配合
usingvarlist=newPooledList<byte>(ArrayPool<byte>.Shared,2048);

可以传入自定义池,比如为特殊场景优化的ArrayPool<T>

Span<T>高效处理

适合序列化/反序列化:

Span<byte>buffer=list.AsSpan();ProcessBuffer(buffer);// 直接操作底层数组,无需复制
搜索和扩展
varlist=newPooledList<string>{"apple","banana","cherry"};boolfound=list.TryFind(s=>s.StartsWith("b"),outstringresult);Console.WriteLine(found?result:"Not found");// 输出: bananavarpooledFromEnumerable=Enumerable.Range(1,5).ToPooledList();// 扩展方法Console.WriteLine(string.Join(", ",pooledFromEnumerable));// 输出: 1, 2, 3, 4, 5pooledFromEnumerable.Dispose();
  • TryFindTryFindLast:返回boolout值,避免null检查。

注意事项与最佳实践

必须调用 Dispose()
  • 否则不会归还数组,导致内存泄漏。

  • 推荐using块。

不要长期持有 Span/Memory
  • 因为数组归还池后可能被其他线程复用。
适用场景
  • 高频率、大数据临时集合。

  • 网络协议解析、日志聚合、临时缓存。

  • 需要Span访问的场景。

不适合场景
  • 长期持有的全局集合。

  • 数据量小且生命周期长的普通集合。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/25 16:19:01

MindAR.js技术解密:构建下一代Web增强现实应用的核心架构

MindAR.js技术解密&#xff1a;构建下一代Web增强现实应用的核心架构 【免费下载链接】mind-ar-js Web Augmented Reality. Image Tracking, Face Tracking. Tensorflow.js 项目地址: https://gitcode.com/gh_mirrors/mi/mind-ar-js MindAR.js作为基于TensorFlow.js的We…

作者头像 李华
网站建设 2026/7/1 6:53:23

wgai开源AI平台从零到一:5步打造专属智能应用系统

还在为AI项目部署复杂、资源占用大而烦恼吗&#xff1f;wgai开源AI平台作为一款开箱即用的Java AI在线训练识别平台&#xff0c;集成了图像识别、OCR文字识别、智能对话等多项AI能力&#xff0c;支持完全离线化部署&#xff0c;让您轻松构建专属的智能应用系统。 【免费下载链接…

作者头像 李华
网站建设 2026/7/2 0:02:32

21、Linux命令行使用与文件操作全解析

Linux命令行使用与文件操作全解析 1. 重定向与管道 在Linux系统中, more 和 less 是非常实用的程序。若想了解 more 的更多功能,可在其提示符下输入 ? 。 管道( | )用于连接两个程序,而重定向则能让程序从文件读取输入或把输出写入文件。重定向标准输出(st…

作者头像 李华
网站建设 2026/7/1 19:52:35

22、Linux 文件操作与系统命令详解

Linux 文件操作与系统命令详解 1. 文件权限机制 在 Linux 系统中,每个文件都有一个所有者(用户 ID)和所属组。默认情况下,文件所属组为创建该文件的用户的默认组。例如,一个部门的所有成员可能属于同一个组,若要与其他组共享文件,可更改文件的所属组。 文件权限分为三…

作者头像 李华
网站建设 2026/7/1 1:37:30

3、每个 Linux 用户都应掌握的基础操作

每个 Linux 用户都应掌握的基础操作 1. 系统电源控制 在 Linux 系统中,正确地开启和关闭系统至关重要,不正确的操作可能会导致数据丢失或损坏。 - 开机 :开启系统电源,这一过程被称为启动(booting)系统。在 Linux 内核启动时,屏幕上会显示许多信息。一段时间后,系…

作者头像 李华
网站建设 2026/6/29 23:09:32

7、Linux 文件管理:共享、查找与权限控制

Linux 文件管理:共享、查找与权限控制 1. 文件共享基础 1.1 分组工作 在 Linux 系统中,组是一组用户的集合,用于共享文件和促进协作。每个组都有唯一的名称和组 ID(gid)。系统管理员可根据用户的组织需求添加新组并分配用户成员资格。例如,在船舶系统中,可能有诸如厨…

作者头像 李华