• 优化多线程安全的内存池


    内存池的实现和管理(一)

    内存池的实现和管理(二)

    前面两篇博客主要介绍了内存池的原理和实现,这篇博客主要是介绍如何优化多线程安全的内存池

    内存池的实现和管理(二)中内存池的实现代码存在的问题

      虽然在内存申请和释放的时候,使用lock_guard()实现了多线程安全的内存池,但是频繁的加锁和解锁带来了不必要的上下文切换开销,导致整个内存池的使用性能下降许多(主要体现在单次申请释放/释放内存需要的时间上升),和直接向系统申请内存的效率差许多

    也就是说,虽然可以减少内存碎片的产生,但是并不能提高申请内存的效率

    优化方案一:

      在多线程情况下,申请内存时加锁是必然的,每次申请向内存池申请内存块的时候都要即时加锁,但是释放内存块的时候我们可以延时释放,做一个定时任务去遍历内存池中管理内存块的链表,加锁一次释放多个内存块,这样就减少了释放内存块时的加锁次数

      在内存池中释放内存块有两个步骤:

      1、把内存使用标记从已使用状态改为未使用

      2、第一个未使用内存块指针的移动

      释放内存时只要求第2步需要互斥进行,所以我们在释放的时候先修改标记状态(不加锁),执行一次定时任务,遍历管理内存块的链表,修改第一个未分配内存块的指针(加锁)

    优化方案二:

      产生冲突的根本原因是因为多个线程共用一个内存池,我们可以让每个线程都拥有一个内存池,这样内存块的申请和释放都在本线程内进行,自然不用加锁

      但是这样在多线程的 情况下使用不方便,内存利用率低下,并且管理内存池很繁琐

      换一个思路,依然时多个线程共用一个内存池,但是我们给不同的线程安排不同的内存使用区域,这样即时不加锁也可以实现内存池的互斥使用

      具体做法是可以给num个内存块进行编号,假设有n个线程,每个线程可使用的内存块个数t=num/n,根据线程id确定该线程使用的内存区域为[t*(id-1),t*id);id的取值范围为[1,n]

    参考博客https://blog.csdn.net/luzubodfgs/article/details/65632609

  • 相关阅读:
    NumPy学习笔记 三 股票价格
    NumPy学习笔记 二
    NumPy学习笔记 一
    Raspberry Pi中可用的Go IDE:liteide
    数学公式字母发音
    Apache Avro# 1.8.2 Specification (Avro 1.8.2规范)二
    Apache Avro# 1.8.2 Specification (Avro 1.8.2规范)一
    用Go校验下载文件之SHA256
    垂直水平居中的几种方式,其他方式还有很多,不再列举
    vue-cli3 每次打包都改变css img js文件名,还有自带版本号
  • 原文地址:https://www.cnblogs.com/-citywall123/p/14139160.html
Copyright © 2020-2023  润新知