C# | 内存池

简介: 内存池可以复用已申请的内存空间,它在程序启动时预先分配一定数量的内存块,当你需要使用内存时,则会从内存池中分配一块空闲内存,也就是说并不是每次都会向系统申请一块新的内存空间。同理,当你使用完一块内存空间后,并不是直接释放内存,而是将其归还到内存池中。内存池就是通过这样一借一还的方式避免了频繁地分配和释放内存,减少了内存碎片和系统开销,提高了程序的性能。

在这里插入图片描述

内存池

@[toc]

前言

在上一篇文章中我们介绍了对象池的概念、优劣和示例。其原理是通过重复利用对象避免了频繁地创建和销毁对象,从而减小系统开销以提高系统的性能。
本章我们将要在上一章内容的基础上再向前一步。我们要解决的新问题是在许多开发场景下我们需要频繁地分配和释放内存,如何利用对象池的模式去优化程序性能呢?


什么是内存池

内存池可以复用已申请的内存空间,它在程序启动时预先分配一定数量的内存块,当你需要使用内存时,则会从内存池中分配一块空闲内存,也就是说并不是每次都会向系统申请一块新的内存空间。
同理,当你使用完一块内存空间后,并不是直接释放内存,而是将其归还到内存池中。内存池就是通过这样一借一还的方式避免了频繁地分配和释放内存,减少了内存碎片和系统开销,提高了程序的性能。
这听起来是不是和对象池?

内存池的优点

  • 避免频繁的内存分配和释放,通过复用内存空间来减小系统开销。
  • 由于主要是最对已申请的内存进行管理,因此可避免一些常见的内存泄漏问题。
  • 避免了频繁内存动态分配形成内存碎片。

内存池的缺点

  • 需要预先分配一定数量的内存块,会固定占用一部分内存空间。
  • 需要管理分配和释放过程。
  • 需求设置合适的内存块大小和数量,需要找到一个性能消耗的平衡点,否则可能会导致内存的浪费或不足。

实现思路

内存池的实现和对象池类似,主要包括以下几个步骤:

  1. 在程序启动时,预先分配一定数量的内存块,并将其保存到内存池中。
  2. 当需要使用内存时,从内存池中分配一块空闲内存块,如果内存池中没有空闲内存块,则需要动态分配新的内存块。
  3. 当内存不再需要时,将其归还到内存池中,而不是直接释放内存。

示例代码

下面是一个内存池实现,它继承自基于上一篇文章的对象池类,并使用byte数组作为内存块的存储。

public class MemoryPool : ObjectPool<byte[]>
{
   
   
    private readonly int _blockSize;

    public MemoryPool(int blockSize, int maxSize)
        : base(() => new byte[blockSize], maxSize)
    {
   
   
        _blockSize = blockSize;
    }

    public byte[] GetBlock()
    {
   
   
        return GetObject();
    }

    public void PutBlock(byte[] block)
    {
   
   
        if (block.Length != _blockSize)
        {
   
   
            throw new ArgumentException("Invalid block size");
        }
        PutObject(block);
    }
}

这个内存池使用byte数组作为内存块,每次分配和释放内存块时,都需要检查内存块的大小是否符合要求。可以根据实际需求设置内存块的大小和数量,避免内存的浪费和不足。


结束语

内存池是一种非常有用的内存管理机制,可以帮助我们更好地控制内存分配和释放的过程,提高程序的性能和稳定性。

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

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

相关文章
|
10天前
|
存储 Java C#
C# 中的值类型与引用类型:内存大小解析
C# 中的值类型与引用类型:内存大小解析
19 2
|
2月前
|
存储 Java C#
C# | 使用Memory<T>高效地读写内存数据
Memory<T>是什么? 它是一种可变大小、可读写的内存块,可以安全地暴露给用户代码进行操作。 为什么要使用Memory<T>? 使用它有许多好处。最主要的是善用它可以提高代码的性能。因为Memory<T>是可变的,所以我们可以直接在内存中操作数据,而不需要进行额外的拷贝操作。 使用Memory<T>还可以减少垃圾回收的压力,因为我们不需要创建新的对象来存储数据。 Memory<T>还可以与Span<T>和ReadOnlySpan<T>类型一起使用,这些类型可以方便地对数据进行访问和操作。
64 0
|
7月前
|
存储 Java C#
C# 垃圾回收机制(GC) 的概述 资源清理 内存管理
C# 垃圾回收机制(GC) 的概述 资源清理 内存管理
|
7月前
|
存储 C#
C# “值类型“和“引用类型“在内存的分配
C# “值类型“和“引用类型“在内存的分配
|
9月前
|
测试技术 C#
C#不通过byte[],直接对内存映射文件复制内存
C#不通过byte[],直接对内存映射文件复制内存
|
9月前
|
C#
关于C# halcon内存泄漏的研究
关于C# halcon内存泄漏的研究
|
SQL 关系型数据库 API
基于C#的ArcEngine二次开发37:循环查询过程的内存管理与性能优化(三)
基于C#的ArcEngine二次开发37:循环查询过程的内存管理与性能优化
基于C#的ArcEngine二次开发37:循环查询过程的内存管理与性能优化(三)
|
SQL 存储 安全
基于C#的ArcEngine二次开发37:循环查询过程的内存管理与性能优化(二)
基于C#的ArcEngine二次开发37:循环查询过程的内存管理与性能优化
|
存储 C#
基于C#的ArcEngine二次开发37:循环查询过程的内存管理与性能优化(一)
基于C#的ArcEngine二次开发37:循环查询过程的内存管理与性能优化
|
Java C#
C#的构造器以及内存状态
C#的构造器以及内存状态
80 0