支持HW团队,就支付宝领取下面的红包吧!(2018年3月31前,就几毛,也会几块,可以和其他红包叠加使用),你领取消费,HW有奖励。红包使用无条件限制,有条件请注意是不是有病毒。

小伙伴们,给大家发红包喽!人人可领,领完就能用。祝大家领取的红包金额大大大!#吱口令#长按复制此消息,打开支付宝就能领取!er1OEj73Uj

登入 注册 | 验证
| 搜索
HelloWorld论坛 : > 计算机科学、技术、教学> 编程专题> 开源免费项目> [原创]ACE内存分配——定长数据分配(一)
 
 
 
 
 
 
类别:ACE 阅读:3578 评论:0 时间:五月 17, 2013, 3:28 p.m. 关键字:ACE 内存

 

想学习ACE内存管理,先看看其他几篇转载的文章。这个是我看后总结出来的

ACE_Message_Block的构造函数定义了三个内存分配器,
这三个内存分配器使用很有讲究的。
ACE_Allocator *allocator_strategy, 真正数据的分配器
ACE_Allocator *data_block_allocator, ACE_Data_Block的分配器
ACE_Allocator *message_block_allocator ACE_Message_Block自身的分配器

这里先研究定长分配器,适合 ACE_Data_Block分配,ACE_Message_Block分配器,前面转载的意见有实现,但是我觉得 要尽量重载现成的代码来实现它

ACE已经有定长分配器,ACE_Cached_Allocator。优点是事先申请一块大内存,然后分成定长小内存工用户使用,所以这样不会增加系统碎片。但是,当用完的时候,不能在申请一块大内存。
所以我现在实现一个分配器,就是ACE_Cached_Allocator的集合,当分配不够的时候,重新申请一个ACE_Cached_Allocator。但是当我用的时候懊恼了,这个类改变了分配函数接口,原来的代码,很多地方要改, 非常不方便。所以也就没怎么测试。有兴趣的可以去测试一下,这里只是说明这种实现方法。要看新的实现策略,请看二。

/***************************************************************
version:  1.0
date: 16/5/2013   17:04
FileName:     BlockAllocator.h
Author:       丁灵峰
Compiled on:   VC.net 2008
-------------------------------------------------------------
Description:
Modification history:
Other:

-------------------------------------------------------------
Copyright (C) 2010 - All Rights Reserved
***************************************************************

****************************************************************/
#if (defined HW_ACE) && (defined HW_ACE_ALLOCATOR)  //使用自定义内存管理
#ifndef _H_hwnet_block_allocator_
#define _H_hwnet_block_allocator_

#include "ace/Malloc.h"
#include <ace/Malloc_T.h>

namespace hwnet
{
        template <class T, class ACE_LOCK>
        class BlockAllocator;
        template <class T, class ACE_LOCK>
        class MinBlockAllocator : public ACE_Cached_Allocator<T, ACE_LOCK>
        {
        public:
                MinBlockAllocator (size_t n_chunks, BlockAllocator<T, ACE_LOCK>* pParent) : ACE_Cached_Allocator(n_chunks) : m_pParent(pParent){}
                void free (void* p)
                {
                        m_pParent->free();
                        return ACE_Cached_Allocator<T, ACE_LOCK>::free(p);
                }
                // 属性
        public:
        protected:
                BlockAllocator<T, ACE_LOCK>* m_pParent;
        };
        template <class T, class ACE_LOCK>
        class BlockAllocator
                : public ACE_New_Allocator
                //: public 
        {
                // 友元
        public:
                // 静态属性
                typedef MinBlockAllocator<T, ACE_LOCK> ACEBlockAllocator;
                // 静态函数
                // 静态工具
                // 接口实现

                // 构造于析构
        public:
                virtual ~BlockAllocator(void)
                {
                        for (std::deque<ACEBlockAllocator*>::iterator ite = m_deqAllocator.begin()
                                ; ite != m_deqAllocator.end()
                                ; ite++)
                        {
                                delete *ite;
                        }
                }
                BlockAllocator(size_t n_chunks)
                        : m_chunks(n_chunks)
                        , m_uSim(0) // 已经使用数量
                {
                        assert(m_chunks > 0);
                }

                // 操作函数
        public:
                T* malloc (ACEBlockAllocator* pAllocator)
                {
                        ACE_GUARD_RETURN (ACE_LOCK, monitor, this->m_lock, NULL);
                        if (m_uSim < m_chunks*m_deqAllocator.size())
                        {
                                // 还有空闲
                                for (int i=m_deqAllocator.size()/2; i>=0; i--)
                                {
                                        for (std::deque<ACEBlockAllocator*>::iterator ite = m_deqAllocator.begin()
                                                ; ite != m_deqAllocator.end()
                                                ; ite++)
                                        {
                                                pAllocator = *ite;
                                                if (pAllocator->pool_depth() > 0)
                                                {
                                                        m_uSim++;
                                                        return (T*)pAllocator->malloc();
                                                }
                                                else
                                                {
                                                        m_deqAllocator.pop_front();
                                                        m_deqAllocator.push_back(pAllocator);
                                                }
                                        }
                                }
                        }
                        // 重新分配
                        pAllocator = new ACEBlockAllocator(m_chunks, this);
                        m_deqAllocator.pop_front(pAllocator);
                        m_uSim++;
                        return (T*)pAllocator->malloc();
                }
                void free ()
                {
                        assert(m_uSim > 0);
                        ACE_GUARD (ACE_LOCK, monitor, this->m_lock);
                        m_uSim--;
                }

                /// Return the number of chunks available in the cache.
                size_t Size (void)
                {
                        return m_chunks*m_deqAllocator.size();
                }
                size_t SizeUser (void)
                {
                        return m_uSim;
                }
                // 提供这个方法,让外部空闲的时候,释放多余空间
                // Resizes the free list to <newsize>
                void resize (size_t newsize)
                {
                        while (newsize < this->Size())
                        {
                                bool bFlage=true;
                                // 释放空间
                                for (std::deque<ACEBlockAllocator*>::iterator ite = m_deqAllocator.begin()
                                        ; ite != m_deqAllocator.end()
                                        ; ite++)
                                {
                                        if ((*ite)->pool_depth() == m_chunks)
                                        {
                                                m_deqAllocator.erase(ite);
                                                newsize -= m_chunks;
                                                bFlage = false;
                                                break;
                                        }
                                }
                                if (bFlage)
                                {
                                        break;
                                }
                        }
                }


                // 工具函数
        private:
        protected:

                // 禁止
        private:
                BlockAllocator(const BlockAllocator&); //复制构造
                BlockAllocator & operator= (const BlockAllocator&); // 等于重载

                // 属性
        public:
        protected:
                ACE_LOCK m_lock;
                size_t m_chunks;
                size_t m_uSim; // 已经使用数量
                std::deque<ACEBlockAllocator*> m_deqAllocator;
        };
}
#endif // #ifndef _H_hwnet_block_allocator_
#endif // HW_ACE HW_ACE_ALLOCATOR  //使用自定义内存管理

 

[挂载人]初学MPEG [审核人]初学MPEG 推荐

个人签名--------------------------------------------------------------------------------

Please Login (or Sign Up) to leave a comment