C# | 对象池

简介: 当我们在做软件开发时经常会需要创建很多的相同且特殊的对象,比如线程、内存、数据库连接、文件句柄等,这类特殊对象有着占用IO资源、创建或销毁的开销大等特点,会导致系统的性能下降和资源浪费。而对象池的出现就是为了解决此类问题,使用对象池来管理这些对象让它们可以被重复使用,从而提高效率。

image.png

对象池

@[toc]

前言

当我们在做软件开发时经常会需要创建很多的相同且特殊的对象,比如线程、内存、数据库连接、文件句柄等,这类特殊对象有着占用IO资源、创建或销毁的开销大等特点,会导致系统的性能下降和资源浪费。而对象池的出现就是为了解决此类问题,使用对象池来管理这些对象让它们可以被重复使用,从而提高效率。


什么是对象池

那么什么是对象池呢?
就是在一个池中预先创建n个对象,当需要使用的时候就从这个池中获取一个实例,并使用完毕后并不销毁释放,而是再将其放回池中,以便可以多次重复使用。

对象池的优点

对象池可以大幅度的减少对象创建和销毁的过程,从而提高程序的运行效率和资源的利用率。此外对象池还可以准确的控制对象创建的数量,因此对于程序的稳定性也有极大助益。

对象池的缺点

对象池的劣势在于它的机制就已经决定了对象池中会有一定数量的对象持续占用内存,如果池中保留的对象的数量过多,可能会导致系统的内存不足,也可能导致其他进程无法拿到系统资源。
还有就是对象池需要进行对象的管理和维护,对于内存池中保留的对象的个数如何取值就需要结合软件和硬件的实际情况进行综合考量了,需要在运行效率和资源消耗上取得平衡。如果管理不当可能会适得其反。


实现思路

设计对象池的思路主要是确定对象池的大小、对象的创建方式、对象的回收方式以及线程安全等问题。通常情况下,我们需要在程序初始化时创建一定数量的对象,并将这些对象存储在对象池中。
当需要使用对象时,从对象池中获取一个可用的对象,使用完毕后将其放回对象池中。如果对象池中的对象数量不足,可以根据需要动态地创建新的对象并添加到对象池中。

简单的对象池示例

下面是一个简易的对象池例子:

public class ObjectPool<T>
{
   
   
    private readonly Func<T> _objectFactory;
    private readonly ConcurrentBag<T> _objects;

    public ObjectPool(Func<T> objectFactory)
    {
   
   
        _objectFactory = objectFactory;
        _objects = new ConcurrentBag<T>();
    }

    public T GetObject()
    {
   
   
        T obj;
        if (_objects.TryTake(out obj))
        {
   
   
            return obj;
        }
        return _objectFactory();
    }

    public void PutObject(T obj)
    {
   
   
        _objects.Add(obj);
    }
}

上面的代码中使用了ConcurrentBag类来实现线程安全的对象管理。
在创建ObjectPool对象时,需要传入一个用于创建对象的委托函数。
当需要获取对象时,先尝试从对象池中获取一个可用的对象,如果对象池中没有可用的对象,则根据委托函数创建一个新的对象。使用完毕后,将对象放回对象池中。

优化:增加保留个数限制

接下来优化一下这个例子,添加一个值限制对象池中保留对象的个数,超出限制的对象会被释放掉。

public class ObjectPool<T>
{
   
   
    private readonly Func<T> _objectFactory;
    private readonly ConcurrentBag<T> _objects;
    private readonly int _maxSize;

    public ObjectPool(Func<T> objectFactory, int maxSize)
    {
   
   
        _objectFactory = objectFactory;
        _objects = new ConcurrentBag<T>();
        _maxSize = maxSize;
    }

    public T GetObject()
    {
   
   
        T obj;
        if (_objects.TryTake(out obj))
        {
   
   
            return obj;
        }
        return _objectFactory();
    }

    public void PutObject(T obj)
    {
   
   
        if (_objects.Count < _maxSize)
        {
   
   
            _objects.Add(obj);
        }
        else
        {
   
   
            IDisposable disposable = obj as IDisposable;
            if (disposable != null)
            {
   
   
                disposable.Dispose();
            }
        }
    }
}

新增了一个名为_maxSize的属性来表示对象池中最多可以保留的对象个数。在PutObject方法中,我们判断当前对象池中的对象数量是否已经达到了最大值,如果是,则释放掉超出限制的对象,否则将对象加入到对象池中。为了保证释放对象时的安全性和可靠性,我们将对象转换为IDisposable接口,如果对象实现了IDisposable接口,则调用其Dispose方法进行释放。

这样,我们就成功地为对象池添加了一个值限制,可以避免对象池中的对象数量过多导致内存溢出和性能下降的问题。当对象池中的对象数量超过限制时,我们可以选择释放对象或者将对象丢弃掉,以保证程序的稳定性和可靠性。


结束语

通过使用对象池,我们可以大幅度减少对象的创建和销毁次数,从而提高程序的运行效率和资源的利用率。同时,我们也需要考虑对象池的大小和限制等问题,以保证程序的性能和可靠性。

在未来的文章中还会介绍其他相关的池,例如线程池、内存池等,更全面地讲解池的相关知识。

如果您觉得本文对您有所帮助,欢迎点赞收藏关注。谢谢!

禁止转载声明:
本文受到版权保护,未经作者许可,严禁转载。任何机构或个人不得以任何形式将本文用于商业用途或进行二次创作、复制、转载等行为。任何未经授权使用本文所涉及的任何内容,作者保留追究法律责任的权利。如需引用本文,请务必注明出处并获得作者的明确授权,感谢您的理解与支持!

相关文章
|
测试技术
CRC-16 MODBUS原理,附实测可用源码
之前做串口解析,CRC校验一直用和校验,就是吧各个位加在一起,新来一个串口协议,是CRC-16 MODBUS的形式校验,不会呀,从网上找了找资源,没有找到源码,都要下载,分享出来。
CRC-16 MODBUS原理,附实测可用源码
|
存储 安全 JavaScript
【分布式技术专题】「授权认证体系」深度解析OAuth2.0协议的原理和流程框架实现指南(授权流程和模式)
在传统的客户端-服务器身份验证模式中,客户端请求服务器上访问受限的资源(受保护的资源)时,需要使用资源所有者的凭据在服务器上进行身份验证。资源所有者为了给第三方应用提供受限资源的访问权限,需要与第三方共享它的凭据。这就导致一些问题和局限:
1036 2
【分布式技术专题】「授权认证体系」深度解析OAuth2.0协议的原理和流程框架实现指南(授权流程和模式)
|
Java 测试技术 Spring
Spring Boot使用@Async实现异步调用
Spring Boot使用@Async实现异步调用
216 0
|
4月前
|
机器学习/深度学习 弹性计算 编解码
阿里云服务器ECS计算型c9i实例收费标准价格表:一年、1小时和1个月费用清单
阿里云ECS计算型c9i实例基于全新CIPU架构,搭载Intel Xeon Granite Rapids处理器,主频3.2GHz,性能稳定,适用于机器学习、视频编码、高性能计算等场景。支持按量付费(小时计费)和包年包月多种模式,提供从ecs.c9i.large到ecs.c9i.48xlarge共12种配置,vCPU从2核至192核,内存4GiB至384GiB,网络带宽最高64Gbps,云盘IOPS达80万。价格灵活,一年付、三年付享大幅折扣,适合不同业务需求。
500 13
|
Web App开发 搜索推荐 安全
|
机器学习/深度学习 数据采集
深度学习之脑电图信号解码
基于深度学习的脑电图(EEG)信号解码是一项重要的研究领域,旨在从脑电图信号中提取有用信息,用于脑-机接口、情绪识别、疾病诊断等应用。
582 5
|
存储 消息中间件 前端开发
.NET常见的几种项目架构模式,你知道几种?
.NET常见的几种项目架构模式,你知道几种?
424 0
|
机器学习/深度学习 运维 分布式计算
大数据技术专业就业前景
大数据技术专业就业前景广阔,广泛应用于互联网、金融、医疗等众多行业,助力企业数字化转型。岗位涵盖大数据开发、分析、运维及管理,如大数据工程师、分析师和系统运维工程师等。这些岗位因专业性和稀缺性而享有优厚薪资,尤其在一线城市可达20万至50万年薪。随着技术进步和经验积累,从业者可晋升为高级职位或投身数据咨询、创业等领域,发展空间巨大。
1530 6
|
弹性计算 专有云 应用服务中间件
nginx在云平台服务几个典型代理场景中的应用案例
在云平台服务中有多种场景需要使用到反向代理,常见的应用场景包括:内网专有云平台访问公网资源、公有云平台访问客户内网IDC机房资源、云产品通过代理访问多个不同的资源等等。笔者总结几种场景配置nginx的7层反向代理、4层反向代理,巧妙实现应用需求。
nginx在云平台服务几个典型代理场景中的应用案例
|
缓存 Java PHP
PHP-Mysql好运图书管理系统--【白嫖项目】
PHP-Mysql好运图书管理系统--【白嫖项目】 CSDN 转过来的,所以格式与内容有些许错误请见谅

热门文章

最新文章