Leveldb Climbing Road--arena

Source: Internet
Author: User
Tags assert

First, reserve knowledge-memory pool

A memory pool is a method used to improve the efficiency of memory allocation and seldom generates heap fragmentation to avoid memory leaks.

Simply put, each application of memory is placed in a container, each need to request the memory to see if it can be allocated directly from the memory pool, if not enough, then first request a new piece of memory into the memory pool, and then allocate. At the end of the release, just release the container-managed memory.


Second, source code analysis

1. Arena.h

Class arena { public:  arena ();   ~arena ();   // return a  pointer to a newly allocated memory block of  "bytes"  bytes.   char* allocate (size_t bytes);   // allocate memory with the  normal alignment guarantees provided by malloc  char*  allocatealigned (size_t bytes);  // returns an estimate of the  total memory usage of data allocated  // by the arena.   size_t memoryusage ()  const {    return reinterpret_cast< Uintptr_t> (Memory_usage_. Nobarrier_load ());   } private:  char* allocatefallback (size_t bytes);               char* allocatenewblock (Size_t block_bytes);        // allocation state   char* alloc_ptr_;              // Memory pointer   size_t alloc_bytes_remaining_;       //the available memory size in the memory pool   // Array of new[] allocated memory blocks  std::vector< char*> blocks_;            //entire Memory pool    // Total memory usage of the arena.  port::AtomicPointer  memory_usage_;        //total memory usage, i.e. how much memory was requested   // No  Copying allowed  arena (const arena&);   void operator= (Const Arena &);};


The entire arena class, only three interface functions can be called, they are allocate, request memory, allocatealigned request byte-aligned memory, Memoryusage, memory usage, three functions. The following three functions are described separately


1.1 Allocate function

Inline char* arena::allocate (size_t bytes)  {  // the semantics of  what to return are a bit messy if we allow  //  0-byte allocations, so we disallow them here  (We don ' t need   // them for our internal use).   assert (bytes > 0);   if  (Bytes <= alloc_bytes_remaining_)  {    char*  result = alloc_ptr_;     //returns the address of the current memory     alloc_ptr_  += bytes;            //moves the pointer to indicate that memory is occupied     alloc_bytes_remaining_ -= bytes;    //reduced amount of available memory      return result;  }  return allocatefallback (bytes);}

If the requested memory size is not larger than the available memory in the current memory pool, then the memory will be obtained directly from the current memory pool, otherwise the memory needs to be re-requested.

The process is as follows:

Is the initial memory pool


Is the case of bytes<alloc_bytes_remaining_ when applying for memory.

When Bytes>alloc_bytes_remaining_, the Allocatefallback function is called.


1.2 allocatefallback function

Char* arena::allocatefallback (size_t bytes)  {  if  (bytes >  KBLOCKSIZE&NBSP;/&NBSP;4)  {    // object is more than a  quarter of our block size.  Allocate it separately     // to avoid wasting too much space in leftover bytes.     char* result = allocatenewblock (bytes);     return  result;  }  // We waste the remaining space in  The current block.  alloc_ptr_ = allocatenewblock (kBlockSize);   alloc_ Bytes_remaining_ = kblocksize;  char* result = alloc_ptr_;  alloc _ptr_ += bytes;  alloc_bytes_remaining_ -= bytes;  return result;}

As can be seen from the code, when bytes is greater than BLOCKSIZE/4, which is more than 1024, then the memory needs to be re-applied directly. However, if the requested memory is less than 1024, it is time to request a piece of 4096 of new memory directly, then set the available memory size to 4096, then the pointer offset and the available memory decreases.

Here are two special areas to watch out for:

1) The requested memory is greater than 1024 after the memory that was previously requested, if the next request for memory is less than alloc_bytes_remaining_, then the memory available in the current memory pool.

2) When the requested memory is greater than alloc_bytes_remaining_, and less than 1024, then this time will be re-request a piece of 4096 size of memory, and the size of alloc_bytes_emaining_ updated to 4096. Here means a waste of less than 1024 of the size of memory, after querying the data found that the author wasted Wasted, as long as the performance OK on the line. Therefore, if you use it yourself, it is part of the optimization.





1.3 Allocatenewblock

char* Arena::allocatenewblock (size_t block_bytes) {char* result = new Char[block_bytes];  Blocks_.push_back (result); Memory_usage_.  Nobarrier_store (Reinterpret_cast<void*> (memoryusage () + block_bytes + sizeof (char*)); return result;}

Request a new piece of memory, put the memory in the memory pool container, and update the memory usage.


1.4 allocatealigned Function

char* arena::allocatealigned (size_t bytes)  {  //to determine whether a number is 2 exponential power of the odd-trick technique   const  int align =  (sizeof (void*)  > 8)  ? sizeof (void*)  : 8;   assert ((align &  (align-1))  == 0);   // pointer  size should be a power of 2  //the odd trick of determining memory alignment and the way to align memory   size_ T current_mod = reinterpret_cast<uintptr_t> (ALLOC_PTR_)  &  (align-1);   size_t slop =  (current_mod == 0 ? 0 : align -  CURRENT_MOD);  size_t needed = bytes + slop;  char* result;   if  (Needed <= alloc_bytes_remaining_)  {    result  = alloc_ptr_ + slop;    alloc_ptr_ += needed;     alloc_bytes_remaining_ -= needed;  } else {    // allocatefallback  Always returned aligned memory    result = allocatefallback (bytes );   }  assert (reinterpret_cast<uintptr_t> (Result  &  (align-1))  = = 0);   return result;}

This function is used to request memory-aligned functions.




Leveldb Climbing Road--arena

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.