在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); }
#pragma once class 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 memory void* start() { return (void*)((size_t)this + sizeof(Page)); } void* end(size_t size) { return (char*)start() + size; } Page* mNextPage; }; //page size is 4kb const 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 memory LinearAllocator::~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; };