FixedAllocator的设计

FRMRESIZE VERSION 1.1 关于Frmresize1.1的说明: FRMRESIZE VERSION 1.1 (CLASS) ---------------------- 作者: SUNVFP Mail: SUNVFP@EYOU.COM 开发日期:2002.10.27 改进日期:2002.10.29 简介: ------------ 有许多狐友关心不同分辨率下表单的显示问题和改变表单大小时表单内各控件的相应改变问题, 也有相当多的狐友写过这方面的类。 我所见过的resize类在使用中都有大大小小的不如人意之处: 如:vfp自己的resize类示例,不支持嵌套等;老外resize类,需要fll动态链接库支持,并且当 控件数量超过256时就会出错等。还有算法不严密,造成控件失位,Frmresize1.0就有这方面的BUG。 我决定重新写一个,代码很简单。大家不妨试用一下,并请不吝提出要求,以方便改进,使之成 为通用类,使后来者少走弯路。 1)Frmresize可以改变字体的相应大小; 2)Frmresize没有嵌套层数的限制,没有控件数量的限制; 3)Frmresize可以有选择的控制各控件是否改变,及如何改变; 4)Frmresize可以自适应不同分辨率。 改进: —————————— 1)增加NoHeightClassList 、NoHeightObjectList 两个属性,可以控制控件的高度是否变化; 2)改进算法,彻底消除失位现象。不论如何调整表单大小,控件的相对位置都不会失位!; 3)因算法的变化,去掉两个不再需要的自定义属性。 用法: ----- 要使用 Frmresize 1.1 必须按以下两步: 添加该类到你的表单, 并设置它的属性. 1) 将 Frmresize 类拖放到你的表单 2) 设置它的属性: 设置类的 FontResize 属性 (在属性窗口的末端) (.T.(默认值)-字体随着作相应大小的改变,.F.-字体大小不变) 设置类的 NoPosClassList 属性 (在属性窗口的末端) (不作位置变化的基类列表,例如commandbutton text等,timer custom hyperlink已排除) 设置类的 NoSizeClassList 属性 (不作大小变化的基类列表,例如commandbutton text等,timer custom hyperlink已排除) 设置类的 NoPosObjectList 属性 (不作位置变化的控件名称列表,例如txt1 COMMAND1 CMDOK等) 设置类的 NoSizeObjectList 属性 (不作大小变化的控件名称列表,例如txt1 COMMAND1 CMDOK等) 设置类的 NoHeightClassList 属性 (不作高度变化的基类列表,例如commandbutton text等,timer custom hyperlink已排除) 设置类的 NoHeightObjectList 属性 (不作高度变化的控件名称列表,例如txt1 COMMAND1 CMDOK等) 注:1。当NoPosClassList和NoSizeClassList 或 NoPosObjectList和NoSizeObjectList中同时包含时,则相关控件及其下层控件不变化。 2。NoSizeClassList或NoSizeObjectList中的相应控件的字体大小不变。 3) 在表单resize事件中写:this.frmresize1.frmresize() 注: 不带任何参数。 4) 在表单init事件中写:this.frmresize1.frmresize(800,600) 注: 参数800,600是指你开发时的屏幕分辨率。 许可: 该类可以没有问题地添加到你的项目. 我要求的唯一东西是如果你改进了程序请让我知道. 发送 Bug 和建议到: sunvfp@eyou.com 或到天堂论坛进行讨论 www.myf1.net 立即下载
再参考了《Modern C++ Design》的FixedAllocator的设计,并且优化了一下算法,虽然最坏时间复杂度还是O(N)的,但是在通常情况下,new/delete的使用已经获得了比较好的性能了。

Chunk.h和version1.0的差不多,只是去掉了析构函数,让Chunk直接被FixedAlloctor操作
Chunk.h
#ifndef CHUNK_H
#define CHUNK_H

#include 
<cassert>

struct Chunk {
    
//初始化一个Chunk
    void init(size_t blockSize, unsigned char blocks); 
    
//分配一个block
    void* allocate(size_t blockSize); 
    
//回收一个block
    void deallocate(void* p, size_t blockSize); 
    
//Chunk的起始地址
    unsigned char* pData_; 
    
//第一个可用的block
    unsigned char firstAvailableBlock_; 
    
//block的块数
    unsigned char blocksAvailable_; 
}
;

void Chunk::init(size_t blockSize, unsigned char blocks) {
    
//从操作系统申请一个Chunk的内存
    pData_ = new unsigned char[blockSize * blocks];
    firstAvailableBlock_ 
= 0;
    blocksAvailable_ 
= blocks;
    unsigned 
char *p = pData_;
    
//每个可用的block存放它下一个可用的block的编号
    for (unsigned char i = 1; i < blocks; i++, p += blockSize) {
        
*p = i;
    }

}


void* Chunk::allocate(size_t blockSize) {
    
if (blocksAvailable_ == 0) return 0;
    unsigned 
char* pRet = pData_ + (firstAvailableBlock_ * blockSize);
    
//更新第一个可用的block
    firstAvailableBlock_ = *pRet;
    blocksAvailable_
--;
    
return pRet;
}


void  Chunk::deallocate(void* p, size_t blockSize) {
    
//判断回收的地址是否合法
    assert(p >= pData_);
    unsigned 
char* toRel = static_cast<unsigned char*>(p);
    
//判断是否合法
    assert((toRel - pData_) % blockSize == 0);
    
*toRel = firstAvailableBlock_;
    firstAvailableBlock_ 
= static_cast<unsigned char>((toRel - pData_) / blockSize);
    
//判断是否产生精度误差
    assert(firstAvailableBlock_ == ((toRel - pData_) / blockSize));
    blocksAvailable_
++;
}



#endif
FixedAllocator.h
毕竟工程还是工程,很多极端数据都是很难用到的,这个与用户使用习惯有关,对于常用的使用new的习惯(连续new,连续delete,连续new/delete)该FixedAllocator都有比较好的性能。
#ifndef FIXEDALLOCATOR_H
#define FIXEDALLOCATOR_H

#include 
"Chunk.h"
#include 
<vector>
using namespace std;

class FixedAllocator {
public :
    FixedAllocator(size_t blockSize);
    
~FixedAllocator();
    
//分配内存
    void* allocate(); 
    
//回收内存
    void deallocate(void* p); 

private :
    
//每个Chunk所含的Block数
    static const int BLOCKS;
    
//block大小
    size_t blockSize_;
    
//该FixedAllocator所含的Chunks
    vector<Chunk> chunks_;
    
//最后一个被用于分配空间的Chunk
    Chunk* lastAllocChunk_;
    
//最后一个被用于释放空间的Chunk
    Chunk* lastDeallocChunk_;
    
//被使用过的Chunks的数
    int numOfUsedChunk_;
    
//判断p是否属于某个chunk
    bool isPtrInChunk(void* p, Chunk* chunk);
}
;

const int FixedAllocator::BLOCKS = 255;

FixedAllocator::FixedAllocator(size_t blockSize) 
: blockSize_(blockSize), lastAllocChunk_(
0), lastDeallocChunk_(0), numOfUsedChunk_(0) {}

FixedAllocator::
~FixedAllocator() {
    vector
<Chunk>::iterator it = chunks_.begin();
    
for (; it != chunks_.end(); it++) {
        delete[] it
->pData_;
    }

}


void* FixedAllocator::allocate() {
    
if (!lastAllocChunk_ || !lastAllocChunk_->blocksAvailable_) {
        
//该Chunk不可用,需要搜索新的Chunk,deallocate保证只有vector中的最后一个块为全空
        bool noBlock = true;
        
if (numOfUsedChunk_ < chunks_.size()) {
            vector
<Chunk>::reverse_iterator it = chunks_.rbegin();
            
for (; it != chunks_.rend(); it++) {
                
if (it->blocksAvailable_ > 0) {
                    lastAllocChunk_ 
= &*it;
                    noBlock 
= false;
                    
break;
                }

            }

        }

        
if (noBlock) {
            
//没有可用Chunk,必须新增一个块
            numOfUsedChunk_++;
            
if (chunks_.size()+1 > chunks_.capacity()) {
                chunks_.reserve(chunks_.capacity() 
+ 1000);
            }

            Chunk newChunk;
            newChunk.init(blockSize_, BLOCKS);
            chunks_.push_back(newChunk);
            lastAllocChunk_ 
= &chunks_.back();
            lastDeallocChunk_ 
= &chunks_.back();
        }

    }

    assert(lastAllocChunk_ 
!= 0);
    assert(lastAllocChunk_
->blocksAvailable_ > 0);
    
return lastAllocChunk_->allocate(blockSize_);
}


inline 
bool FixedAllocator::isPtrInChunk(void* p, Chunk* chunk) {
    
return (p >= chunk->pData_) && (p < chunk->pData_ + (blockSize_ * BLOCKS));
}


void FixedAllocator::deallocate(void* p) {
    vector
<Chunk>::iterator pChunkToRelease;
    
if (!isPtrInChunk(p, lastDeallocChunk_)) {
        
//要释放的空间不在lastDeallocChunk中
        
//从lastDeallocChunk开始up和down方向查找
        vector<Chunk>::iterator up = lastDeallocChunk_+1;
        vector
<Chunk>::iterator down = lastDeallocChunk_;
        vector
<Chunk>::iterator begVec = chunks_.begin();
        vector
<Chunk>::iterator endVec = chunks_.end();
        
int t = 0;
        
while (down != begVec || up != endVec) {
            t 
^= 1;
            
if (up == endVec) t = 0;
            
if (t) {
                
//up方向
                if (up != endVec) {
                    
if (isPtrInChunk(p, up)) {
                        pChunkToRelease 
= up;
                        
break;
                    }

                    up
++;
                }

            }
 else {
                
//down方向
                if (down != begVec) {
                    down
--;
                    
if (isPtrInChunk(p, down)) {
                        pChunkToRelease 
= down;
                        
break;
                    }

                }

            }

        }

    }
 else {
        pChunkToRelease 
= lastDeallocChunk_;
    }

    
    assert(
&*pChunkToRelease != 0);
    pChunkToRelease
->deallocate(p, blockSize_);
    lastDeallocChunk_ 
= pChunkToRelease;

    
if (pChunkToRelease->blocksAvailable_ == BLOCKS) {
        
//该块已经空
        numOfUsedChunk_--;
        Chunk
* it = &chunks_.back();
        
if (it->blocksAvailable_ == BLOCKS) {
            
//若vector末尾的chunk已是空块,直接把pChunkToRelease删除
            if (it != pChunkToRelease) {
                delete[] pChunkToRelease
->pData_;
                chunks_.erase(pChunkToRelease);
            }

        }
 else {
            
//若vector末尾的chunk非空,把pChunkToRelease移到vector末尾
            Chunk tmp(*pChunkToRelease);
            chunks_.erase(pChunkToRelease);
            chunks_.push_back(tmp);
        }

        lastDeallocChunk_ 
= &chunks_.front();
    }

}


#endif

MemPool.h
比起1.0少了很多代码,这个是当然的,因为很多细节都被封装在FixedAllocator里面,而且还用了STL 的vector,代码又减少了许多,但是测试时候发现vector貌似比自己写的list慢了点,估计原因是那个erase在list里面是O(1)但是 vector是O(n)的。
#ifndef MEMPOOL_H
#define MEMPOOL_H

#include 
"FixedAllocator.h"

class MemPool {
public :
    MemPool(size_t blockSize) : blockSize_(blockSize), allocator_(
new FixedAllocator(blockSize)) {}
    
~MemPool() {
        delete allocator_;
    }

    
void* alloc(size_t size) {
        
if (size != blockSize_) {
            
return ::operator new(size);
        }

        
return allocator_->allocate();
    }

    
void free(void* p, size_t size) {
        
if (!p) return ;
        
if (size != blockSize_) {
            ::
operator delete(p);
        }

        allocator_
->deallocate(p);
    }

private :
    FixedAllocator
* allocator_;
    size_t blockSize_;
}
;


#endif

test.cpp
#include <iostream>
#include 
"FixedAllocator.h"
#include 
"MemPool.h"
#include 
"time.h"
using namespace std;

class TestClassA {
public :
    
int a;
    
static void* operator new(size_t size);
    
static void operator delete(void *p, size_t size);
    
static MemPool memPool;
}
;

inline 
void* TestClassA::operator new(size_t size) {
    
return memPool.alloc(size);
}


inline 
void TestClassA::operator delete(void* p, size_t size) {
    memPool.free(p, size);
}


MemPool TestClassA::memPool(
sizeof(TestClassA));

class TestClassB {
public :
    
int b;
}
;

const int CTIMES = 1000000;

TestClassA
* pa[CTIMES];
TestClassB
* pb[CTIMES];

int main() {
    
//测试新建1000000个SmallObjet所需要的时间
    int i;
    clock_t begA, begB, endA, endB;
        
    begB 
= clock();
    
for (i=0; i<CTIMES; i++) {
        pb[i] 
= new TestClassB;
        }

    endB 
= clock();
    printf(
"Not Used MemPool Time For New = %d ms/n", endB - begB);
    

    begA 
= clock();
    
for (i=0; i<CTIMES; i++) {
        pa[i] 
= new TestClassA;
    }


    endA 
= clock();
    printf(
"Used MemPool Time For New = %d ms/n", endA - begA);


    begB 
= clock();
    
for (i=CTIMES-1; i>=0; i--) {
        delete pb[i];
    }

    endB 
= clock();
    printf(
"Not Used MemPool Time For Delete = %d ms/n", endB - begB);
    

    begA 
= clock();
    
for (i=0; i<CTIMES; i++) {
        delete pa[i];
    }

    endA 
= clock();
    printf(
"Used MemPool Time For Delete = %d ms/n", endA - begA);
    
    
    begB 
= clock();
    
for (i=0; i<CTIMES; i++) {
        pb[i] 
= new TestClassB;
        delete pb[i];
    }

    endB 
= clock();
    printf(
"Not Used MemPool Time For New/Delete = %d ms/n", endB - begB);


    begA 
= clock();
    
for (i=0; i<CTIMES; i++) {
        pa[i] 
= new TestClassA;
        delete pa[i];
    }

    endA 
= clock();
    printf(
"Used MemPool Time For New/Delete = %d ms/n", endA - begA);


    
return 0;
}


测试结果如下:
Not Used MemPool Time For New = 360 ms
Used MemPool Time For New = 156 ms
Not Used MemPool Time For Delete = 531 ms
Used MemPool Time For Delete = 266 ms
Not Used MemPool Time For New/Delete = 906 ms
Used MemPool Time For New/Delete = 344 ms
Press any key to continue

明显比version1.0好很多,接着准备写versiong1.2,希望获得更好的封装,同时优化再优化FixedAllocator的算法。还有推荐大家看《Modern C++ Design》这本书,真的很好。

 
北斗三号PPP-B2b信号实战指南:从接收机配置到精度验证全流程 本文提供了北斗三号PPP-B2b信号从硬件配置到数据处理的全流程实战指南。详细解析了信号特性、接收机关键参数设置,并以飞纳接收机和Mass软件为例,演示了数据解算与精度验证方法。通过覆盖中国多地区的联调测试案例,验证了PPP-B2b服务可实现分米级实时定位精度,为无网络地区高精度应用提供了可靠解决方案。 阅读详情

相关推荐

Win10或Win8下ObjectARX2015 Wizard向导创建项目失败解决方法

[原创]objectARX 2015 Wizard安装向导在Win8/win10下无法创建项目的解决方法总结 by edata @2017-5-1 objectARX 2015 Wizard安装向导在Win8/win10下无法创建项目的解决方法 因为Win8/Win10对系统盘(默认c:)使用了高级权限管理,所以在此盘下操作文件的修改工作都需要管理员权限才行。 基于这个原因,导致非管理员安

edata的博客 7029

【UEC++】 容器TArray—性能优化

对于容器类型(比如TArray、TSet、TMap等等),如果您在关键行需要对代码进行操作,很多情况下,您需要考虑的最重要的事是使用正确的容器。举例来说,如果您需要保持一列特有元素并需要经常添加、移除或搜索它们,那么您可以使用TArray这个容器,但实际上TSet是一个更好的选择。 如果您想要在紧密的存储空间中非常快地进行元素迭代,那么您可以选择TArray。但是,您需要在写代码时查看一下其他操作(添加、移除等等)的含义。这里我们有一些简单方法,可以帮助您确认对TArray的使用最优化,从而不必在发布游戏

cjc_hoderxx123的专栏 1892

手把手教你用AirSim和Unreal4在Ubuntu上创建自定义无人机仿真场景

本指南详细介绍了如何在Ubuntu系统上使用AirSim和Unreal Engine 4搭建高精度无人机仿真环境。从硬件配置、驱动安装到Unreal Engine编译和AirSim集成,手把手教你创建自定义场景,适用于算法验证和开发测试。

y7z8a的博客 256

Unreal是如何驾驭内存的 第10章 容器内存管理——TArray、TMap、TSet深度剖析

摘要 本章深入解析了UE核心容器TArray、TMap和TSet的内存管理机制。TArray采用几何增长策略(约1.375倍)配合Binned2分配器的量化特性,在扩容时优化内存使用;通过MoveTemp实现高效内存转移,避免深拷贝开销。TMap和TSet基于开放寻址哈希表实现,采用二次探测解决冲突。特殊分配器如InlineAllocator可避免小数组的堆分配,而FixedAllocator则实现固定容量容器。理解这些容器的内存行为对编写高效UE代码至关重要,特别是在处理大规模数据时,合理使用Reserv

腾TO的技术博客 425

区块链技术在碳足迹数据存证与溯源中的应用深度解析

消费者扫描产品上的二维码,即可通过区块链浏览器查询到该产品的数字碳标签,并追溯其从茶园到货架的每一步碳足迹数据,以及这些数据是如何被智能合约自动计算和认证的,从而建立起强大的品牌信任。如果说哈希链解决了数据的“存”与“证”的问题,那么智能合约则解决了数据“用”与“管”的自动化问题。综上所述,虽然针对“碳足迹数据可追溯性”这一特定应用场景的公开、标准化的性能基准案例尚不丰富,但现有研究和企业级解决方案(特别是联盟链)已经证明,通过合理的技术选型和架构设计,区块链的性能可以满足实际商业需求。

百态·数智思维 | 聚焦大数据、量化与未来AI 1106

树莓派视觉小车实战:OpenCV驱动的智能物体追踪系统

本文详细介绍了如何从零开始构建一个基于树莓派的智能视觉小车,实现物体跟踪功能。通过OpenCV进行图像处理,结合颜色与轮廓识别算法,让小车能够实时锁定并追踪特定目标。内容涵盖硬件搭建、软件环境配置、核心代码解析及运动控制逻辑,为创客和开发者提供了完整的实战指南。

weixin_29047545的博客 143

Mybatis逆向工程工具改进版(Version 1.1)

Mybaits逆向工程,基于Java Config形式,生Model,Mapper,Mapper.xml 。生成注释,Model和Mapper可继承相应的SuperModel,SuperMapper

点滴之积 2247

腾讯云TDSQL MySQL版 - 开发指南兼容性

语言结构 分布式实例支持所有 MySQL 使用的文字格式,包括: String Literals Numeric Literals Date and Time Literals Hexadecimal Literals Bit-Value Literals Boolean Literals NULL Values String Literals String Literals 是一个 bytes 或者 characters 的序列,两端被单引号'或者双引号"包围,TDSQL MySQL版

weixin_43872058的博客 909

第一篇------Virtual I/O Device (VIRTIO) Version 1.1

virtio-v1.1-cs01

Phoenix_zxk的博客 2603

实测昇腾310P跑Qwen3有多慢?手把手带你部署vLLM并记录性能数据

本文实测了昇腾310P在vLLM框架下部署Qwen3模型的性能表现,详细记录了2.5 tokens/s的生成速度及其技术瓶颈。通过环境搭建、基准测试和深度分析,揭示了计算资源利用率不足等关键问题,并提供了实用的优化技巧与监控方案,帮助开发者更好地理解和优化昇腾平台上的大模型部署。

weixin_28724319的博客 895

量化交易零基础入门教程

特点 从零开始教编程。靠谱的量化交易学习资源稀少,且具有不讲编程、代码较难、过多等不适合新手等问题,本教程中则会从零开始教编程,解决量化入门过难过编程门槛这一问题。 量化与编程相结合。本教程不仅会教编程,而且会尽量结合量化情景,减少“我要做量化交易为什么要看这些用来培训程序员的东西”的愤懑。 简易精炼,快速入门。尽量只讲最核心最常用的知识,助你快速摆脱想学习量化却处处陌生不知所措的茫然的新手阶段。 读前说明 文后会有自测与自学,包括一些额外的延伸自学内容以及稍有难度的自测题目。 最最最基础的股票.

JanLEE 2885

内存池(version1.1)

再参考了《Modern C++ Design》的FixedAllocator的设计,并且优化了一下算法,虽然最坏时间复杂度还是O(N)的,但是在通常情况下,new/delete的使用已经获得了比较好的性能了。Chunk.h和version1.0的差不多,只是去掉了析构函数,让Chunk直接被FixedAlloctor操作Chunk.h#ifndef CHUNK_H#define CHUNK_H

yysdsyl的专栏 922

xtop:multi_driven_net与incomplete_timing_cell fail reason 分析

man multi_driven_net”可以得知,这个问题是multi driven结构引起的,使用命令“get_failed_pins -reason multi_driven_net”,获取violation pin。“man incomplete_timing_cell”可以得知,这个fail reason的原因是缺少timing library cell,检查并补全后这个错误就显示了。这里选择的解决方法是修改lib文件,把inout改成input,重新lib2idb。通过这种方法解决了问题。

m0_61544122的博客 566

侯捷老师 C++内存管理-第四讲 学习笔记

侯捷老师 C++内存管理-第四讲 Loki :: allocator

weixin_56042518的博客 488

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

内存管理——小型对象分配器实践输出

【注】此实践的基本思路来自《Modern C++ Design》 四层结构 实现Chunk struct Chunk { Chunk() : pData(nullptr), firstAvailableBlock_(0), blocksAvailable_(0) { } Chunk(size_t blockSize, unsigned char blocks) { pData = new unsigned char[blockSize * blocks]; firstAvailab

xunye的博客 1478

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

侯捷 C++内存管理 第四章节 loki::allocator 笔记

侯捷 C++内存管理 第四章节 loki::allocator 笔记

weixin_48956191的博客 1399

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Modern C++ Design 笔记 第四章 Small-Object Allocation

在频繁的new/delete的时候容易衍生memory fragment, 我想设计这个Allocator的初衷就在这里。初看到这个题目的时候不由的让人联想到的东西是std::allocator.  所以我们就从MS的STL中看看std::allocator的实现。templateclass _Ty> inline    _Ty _FARQ *_Allocate(_SIZT _Coun

斯巴达的勇士已经是雅典的臣民了。。。 2552

C++ 内存管理(三)----Loki allocator

C++ 内存管理(三)----Loki allocator一、上中下三个classes 一、上中下三个classes 最表层的struct SmallObjAllocator: 1.FixedAllocator类型指针 pLastAlloc和 pLastDealloc分别指向其内部存放的首个元素[FixedAllocator类对象]的首地址 和 末尾元素[FixedAllocator类对象]的地址的下一个位置; 2.chunkSize为指定chunk的内存大小 class FixedAllocator{

Scostifile的博客 407

Modern C++ design第四章

本章介绍了一个小型对象分配器. 因为过多的小型对象( 例如仿函数, 智能指针)的分配释放, 会导致内存碎片, 内存耗费过多, 分配速度过慢等问题。 故而在需要大量小型对象的系统中, 一个分配器是非常必要的。本章介绍的这个分配策略共由四层组成, 第一层是Chunk , 一块大内存。 一个Chunk可以分配最多255个小型对象。 Chunk内的可用内存, 通过一个链表连接起来。 第二层是F

dummyedu的专栏 742

请教高手 一道据说是微软面试题

Assignment 1:作业要求:    重载C++中的 operator new()和 operator delete()函数,为用户程序环境提供获得和释放批量动态空间函数接口;详细描述:     对于一个自定义类,MyClass:       Public class MyClass        {              public:                     MyCl

bobogu的专栏 644

技术系列之 内存管理(二)

作者:CppExplore 地址:http://www.cppblog.com/CppExplore/2、定长内存池。典型的实现有LOKI、BOOST。特点是为不同类型的数据结构分别创建内存池,需要内存的时候从相应的内存池中申请内存,优点是可以在使用完毕立即把内存归还池中,可以更为细粒度的控制内存块。    与变长的相比,这种类型的内存池更加通用,另一方面对于大量不同的数据类型环境中,会浪费不少内

actionmoon的专栏 513

不太懂 atomic?我花了一下午从 freelist 写到 CAS 无锁栈

一个下午,10 个功能,从固定大小分配器到 CAS 无锁栈。这篇文章记录每一层的设计思路和核心代码。适合想理解"malloc 内部怎么工作"的 C++ 初学者。

Elizabeth_Booker的博客 307

C++内存管理(候捷)第四讲 笔记

候捷内存管理学习笔记

Mhypnos的博客 1194

loki::allocator

文章目录1. loki::allocator 结构2. loki::allocator 使用实例3. loki::allocator 具体实现3.1 Chunk 部分实现3.2 FixedAllocator 部分实现4. loki::allocator 总结 loki::allocator 是由C++编委会一成员所写,可找到的最新版本是 loki-0.1.7.exe,所以从未发行过。但是并不妨碍学习其中的设计思路和实现方法。其实现颇有暴力美学的味道,但是又能够较好的实现功能,相比于std::alloc,

To the beyond and infinity! 540

小对象的分配技术

  小对象分配技术是Loki提高效率的有效途径,Loki里广泛使用小对象, 如果使用系统默认分配器,因为薄记得缘故,可能代价在400%以上,所以这个是必须要解决的问题。我们首先来谈Chunks。 1.MemControlBlock结构 struct MemControlBlock {    bool    available_;    MemControlBlock*    prev_...

老浣熊 357

(内存管理)47

47: FixedAllocator里面两根指针,这两根指针指向Chunk,而Chunk这一串是Vector, 假如串起来有一万个Chunk,第327个Chunk上一次才给出去过区块,则allocChunk指向这个 Chunk,若还需要给出区块,则优先考虑allocChunk指向的Chunk deallocChunk-------------->上一次回收到第n号,这次回收也先判断是不是在第n号 if(allocChunk == 0 || allocChunk_->bl...

weixin_44778039的博客 106
上一篇: TCP/IP详解
下一篇: const和指针组合的变化
suacker
博客等级 码龄24年 46粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值