LinearAllocator内存分配

来源:互联网 发布:辐射4 室内光源优化 编辑:程序博客网 时间:2024/06/14 15:26

简介:

在Android4.4中,在hwui将以前的绘制命令由原来的枚举类型,全部以类的形式呈现(一是为了便于扩展,二是由于加入延时渲染列表,不得不用类来实现),抽象类为DisplayListOp,在该类中重载了new的方法,即用了new placement的方式,统一分配内存,而不是每个操作自己分配,即用了LinearAllocator来管理每个操作需要申请的内存,这样能够提升申请内存的性能,同时能够便于统一管理。

class DisplayListOp {public:    // These objects should always be allocated with a LinearAllocator, and never destroyed/deleted.    // standard new() intentionally not implemented, and delete/deconstructor should never be used.    virtual ~DisplayListOp() { CRASH(); }    static void operator delete(void* ptr) { CRASH(); }    /** static void* operator new(size_t size); PURPOSELY OMITTED **/    static void* operator new(size_t size, LinearAllocator& allocator) {        return allocator.alloc(size);    }

实现:

LinearAllocator主要用于多个对象需要重复申请,同时这些对象的生命周期都类似的情况。
实现原理即需要使用该内存分配的对象,需要使用new placement的方式,不需要自己申请内存,申请内存统一使用LinearAllocator来申请。在LinearAllocator内部分配了主要通过页的方式来申请内存,每页4kb,每页之间通过单链表的方式来组织。
1. 当需要申请内存时,判断当前页是否满足需要内存大小的申请。
2. 如果满足,则直接返回当前内存,将指针游标指向下一个内存开始。
3. 如果不满足,则需要重新申请一页大小的内存,将内存除了Page结构大小外的地址开始返回。
4. 如果需要,也可以在每个申请的内存之间加入一定的标记,用于内存的管理。
#pragma onceclass LinearAllocator{public:LinearAllocator();~LinearAllocator();void* alloc(size_t size);private:class Page;Page* newPage(size_t size);Page* mHeadPage;Page* mCurrentPage;void* mNext;size_t mMemoryCount;};
#include <stdio.h>#include <stdlib.h>#include "LinearAllocator.h"class LinearAllocator::Page{public:Page(){mNextPage = NULL;}~Page(){}void* operator new(size_t size, void* buf){return buf;}//this is the memory begin, add the page size is 4, so the next is the real memoryvoid* start(){return (void*)((size_t)this + sizeof(Page));}void* end(size_t size){return (char*)start() + size;}Page* mNextPage;};//page size is 4kbconst int ONE_PAGE_SIZE = 4096;#define ALIGN_INT(x) (x + sizeof(int) -1) &~(sizeof(int) -1)LinearAllocator::LinearAllocator(){mHeadPage = mCurrentPage = NULL;mNext = NULL;mMemoryCount = 0;}//delete all the memoryLinearAllocator::~LinearAllocator(){Page* p = mHeadPage;while(p){Page* pNext = p->mNextPage;p->~Page();free(p);p = pNext;}}LinearAllocator::Page* LinearAllocator::newPage(size_t size){size_t allocSize = ALIGN_INT(sizeof(Page)+ size);mMemoryCount += allocSize;void* p = malloc(allocSize);return new(p) Page();}void* LinearAllocator::alloc(size_t size){size = ALIGN_INT(size);if (NULL == mHeadPage){mHeadPage = mCurrentPage = newPage(ONE_PAGE_SIZE);mNext = mCurrentPage->start();}else if ((char*)mNext + size > mCurrentPage->end(ONE_PAGE_SIZE)){Page* p = newPage(ONE_PAGE_SIZE);mCurrentPage->mNextPage = p;mCurrentPage = p;mNext = mCurrentPage->start();}void* ptr = mNext;mNext = (char*)mNext + size;return ptr;}

使用方式:

class AllocTest{public:AllocTest(){mCount ++;a = mCount;b = a+1;c = b+1;}void* operator new (size_t size, LinearAllocator& linearAlloc){return linearAlloc.alloc(size);}void dump(){cout<<"a = "<<a<<"  b="<<b<<"  c="<<c<<endl;}int a;int b;int c;static int mCount;};int AllocTest::mCount = 0;class LinearAllocTest{public:LinearAllocTest(){AllocTest* test1 = new(mLinearAlloc)AllocTest();AllocTest* test2 = new(mLinearAlloc)AllocTest();AllocTest* test3 = new(mLinearAlloc)AllocTest();AllocTest* test4 = new(mLinearAlloc)AllocTest();test1->dump();test2->dump}~LinearAllocTest(){}private:LinearAllocator mLinearAlloc;};

同时也可以参考Android源码:
system/core/include/utils/LinearAllocator.h
0 0
原创粉丝点击