{"id":23455452,"url":"https://github.com/aden-q/memory-pool","last_synced_at":"2025-04-11T03:48:00.403Z","repository":{"id":107313273,"uuid":"138714536","full_name":"Aden-Q/memory-pool","owner":"Aden-Q","description":"Object-Oriented  Programming Course Project","archived":false,"fork":false,"pushed_at":"2020-05-20T21:14:24.000Z","size":153,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-11T03:47:56.840Z","etag":null,"topics":["cplusplus","freelists","memory-allocator","memory-pool","stl"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Aden-Q.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-26T09:19:59.000Z","updated_at":"2025-03-11T07:56:05.000Z","dependencies_parsed_at":"2024-04-01T18:15:06.368Z","dependency_job_id":null,"html_url":"https://github.com/Aden-Q/memory-pool","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aden-Q%2Fmemory-pool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aden-Q%2Fmemory-pool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aden-Q%2Fmemory-pool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aden-Q%2Fmemory-pool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Aden-Q","download_url":"https://codeload.github.com/Aden-Q/memory-pool/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248339267,"owners_count":21087214,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cplusplus","freelists","memory-allocator","memory-pool","stl"],"created_at":"2024-12-24T03:31:27.483Z","updated_at":"2025-04-11T03:48:00.381Z","avatar_url":"https://github.com/Aden-Q.png","language":"C++","readme":"# STL Vector Memory Pool\n\n# 1. Overview \n\n**Standard Template Library** provides a mechanism of memory allocation and deallocation for **STL Containers**, known as **std::allocator**.While **stl::allocator** has different implementation versions vary with different versions of **compiler** and **C++ standard library**. Compared to a simple version of memory management implemented with only **new** and **delete**, **stl::allocator** has the advantages of **reducing quantity of memory fragments** and **optimize memory allocation speed** in the meanwhile.  My job is to implement a memory allocator for **STL** **vector** and **list** and optimize it using **memory pool**, supporting arbitrary memory size allocation request. Memory pool maintain several memory blocks for allocation, avoiding considerable cost of frequent memory applying operation from system. Because there are so many kinds of memory pool version, it should be noted that the memory pool implemneted by myself is based on **\"Freelists\"**.\n\n\n\n# 2. Principle Introduction \n\nThe following figure shows the architecture of **memory pool** based on **\"Freelists\"**:\n\n![](./images/memorypool.png)\n\nClass memory pool has 16 freelists in total, using 8-byte alignment standard (efficient for large number of allocations). As shown above, each freelist is defined to maintain equal size memory blocks. When memory application of size **n** occurs, the memory pool will find the **\"optimal“** freelist for allocation, which mean the **size of memory block** in this freelist is closest to user's request of size **n**. Then this block will be returned to user and pointers will be modified. Then one round of allocation ends. When this freelist **lacks of memory for allocation**. Then memory pool will be **expanded** on this freelist for futher allocation. In another case, when memory block allocated should be returned, it will be **returned to memory pool rather than operating system**, bringing befits for memory allocation in the future.\n\n\n\n# 3. Environment \n\n## SYETEM \n\n**Windows 10 (Virtual Machine On MacOS)**\n\n## IDE   \n\n**Visual Studio 2017**\n\n## SDK   \n\n**Windows SDK, version 10.0.17134.0**\n\n## Other Hardware \n\n**Memory:** 16GB 2133MHz LPDDR3\n\n**CPU:** 2.9 GHz Intel Core i7\n\n\n\n# 4. File Structure \n\n- README.md: markdown file\n- memorypool\n  + Debug: executable file folder\n  + memorypool: containing source code, head file and other dependancies\n  + memorypool.sln: project file for **Visual Studio 2017**\n\n\n\n# 5. USAGE \n\n## How to build \n\nSimply open memorypool.sln in **Visual Studio 2017—\u003eGenerate a solution—\u003eRun**\n\nOr you can build with source code and head file but feasibility may not be guranteed.\n\n\n\n# 6. Class Declaration Specification \n\n## 6.1 Standard Interfaces \n\nInterfaces of **stl::allocator** which must be conformed with:\n\n``` c++\ntemplate\u003ctypename T\u003e\nclass MemoryPool\n{\npublic:\n\n\t//some typedef\n\ttypedef T value_type;\t\t\t\t\t//type value\n\ttypedef T *pointer;\t\t\t\t\t\t//type pointer\n\ttypedef const T *const_pointer;\t\t\t//const type pointer\n\ttypedef T \u0026reference;\t\t\t\t\t//type reference\n\ttypedef const T \u0026const_reference;\t\t//const type reference\n\ttypedef size_t size_type;\t\t\t\t//size_t alias\n\ttypedef ptrdiff_t difference_type;\t\t//difference of poitner value\n\n\t//rebind allocator\n\ttemplate \u003cclass U\u003e\n\tstruct rebind\n\t{\n\t\ttypedef MemoryPool\u003cU\u003e other;\n\t};\n    \n    //member functions\n    \n    //allocate memory\n\tT *allocate(size_type n = 1, const void *hint = 0);\n\n\t//return memory to memory pool or operating system\n\tvoid deallocate(T *p, size_type n = 1);\n\n\t//object constructor, copy initialization\n\tvoid construct(pointer p, const T \u0026value);\n\n\t//object destructor, call destructor\n\tvoid destroy(pointer p);\n    \n\t//reload destructor\n\tvoid destroy(T *first, T *last);\n    \n\t//get address\n\tpointer address(reference x);\n\n\t//get const address\n\tconst_pointer address(const_reference x);\n}\n```\n\n\n\n## 6.2 Other Member Variables And Member Functions \n\n**Member Variables:**\n\n``` c++\nprivate:\n\tstatic const int Align = 8;                        //bytes for alignment\n\tstatic const int Maxbytes = 128;                   //maximum bytes of freelists\n\tstatic const int NumberOfLists = Maxbytes / Align; //size of freelists\n\tstatic const int NumberOfAddedNode = 20;           //default add 20 nodes to the lists\n```\n\n**Member Functions:**\n\n``` c++\nprivate:\n\tstatic inline size_t ROUND_UP(size_t bytes) { return (((bytes)+(size_t)Align - 1) \u0026 ~((size_t)Align - 1)); } \t//calculate round up quantity by 8\n\n\t//union to manage freelists, linked lists\n\tunion Obj {\n\t\tunion Obj *next;\n\t\tchar data[1];\n\t};\n\n\tstatic Obj *freelists[NumberOfLists]; //freelists declaration\n\tstatic inline size_t index_freelist(size_t bytes)\t//calculate index of freelists according to size specified\n\t{\n\t\treturn (((bytes)+(size_t)Align - 1) / (size_t)Align - 1);\n\t}\n\tstatic void *refill(size_t n);                      //padding freelists\n\tstatic char *blockAlloc(size_t size, size_t \u0026nobj); //refer to memory block for allocation\n\n\tstatic char *startOfFree; //start address for allocation of memory pool\n\tstatic char *endOfFree;   //end address for allocation of memory pool\n\tstatic size_t heap_size;  //size of heap for allocation\n```\n\n**Static Member Variables Initialization:**\n\n``` c++\ntemplate \u003ctypename T\u003e char* MemoryPool\u003cT\u003e::startOfFree = 0;\ntemplate \u003ctypename T\u003e char* MemoryPool\u003cT\u003e::endOfFree = 0;\ntemplate \u003ctypename T\u003e size_t MemoryPool\u003cT\u003e::heap_size = 0; \ntemplate \u003ctypename T\u003e typename MemoryPool\u003cT\u003e::Obj* MemoryPool\u003cT\u003e::freelists[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };\n```\n\n\n\n**Note: Please refer to source code for more details, definition of functions will not be listed due to space limitation.**\n\n\n\n# 7. Performance Test \n\n## 7.1 Simply Use \"new\" and \"delete\" \n\nIn this case, element assignment is omitted, as a result of which actual time cost is even more. But the difference will not be large.\n\nThe figure following shows the performance of using only **\"new\" and \"delete\"**\n\n| TestSize | Time/s  |\n| :------: | :-----: |\n|   1000   | 1.88885 |\n|   2000   | 2.71974 |\n|   3000   | 3.78392 |\n|   4000   | 4.49549 |\n|   5000   | 5.83866 |\n|   6000   | 7.25714 |\n|   7000   | 9.06466 |\n|   8000   | 11.2784 |\n|   9000   | 12.1318 |\n|  10000   | 13.8354 |\n\n\n\n## 7.2 Use stl::allocator \n\n\n\n| TestSize |  Time/s  |\n| :------: | :------: |\n|   1000   | 0.090489 |\n|   2000   | 0.151623 |\n|   3000   | 0.181994 |\n|   4000   | 0.234633 |\n|   5000   | 0.300228 |\n|   6000   | 0.378082 |\n|   7000   | 0.410464 |\n|   8000   | 0.439271 |\n|   9000   | 0.488316 |\n|  10000   | 0.548868 |\n\n\n\n## 7.3 Use MemoryPool \n\n\n\n| TestSize |  Time/s  |\n| :------: | :------: |\n|   1000   | 0.154164 |\n|   2000   | 0.215237 |\n|   3000   | 0.262408 |\n|   4000   | 0.376538 |\n|   5000   | 0.421113 |\n|   6000   | 0.465753 |\n|   7000   | 0.534237 |\n|   8000   | 0.551913 |\n|   9000   | 0.622731 |\n|  10000   | 0.684331 |\n\n\n\n## 7.4 Figure \n\nPerformance of **new/delete**, **stl::allocator** and **memory pool**:\n\n![](./images/three.png)\n\n Performance of  **stl::allocator** and **memory pool** only:![](./images/two.png)\n\n\n\n# 8. Analysis Of Performance \n\nAs the tables and figures above show, using **\"new\"** and **\"delete\"** is inefficient. In contrast, **stl::allocator** and **memory pool** show good performance in terms of program efficiency, while **stl::allocator** performs better to some extend. Time complexity is difficult to analyze because lack of knowledge about memory management of operating system. It can be concluded that **stl::allocator** may be implemented using **memory pool** or other technique like **ring cache**, rather than simple packaging of **\"new\"** and **\"delete\"**.\n\n\n\n# 9. Credit \n\n- **Author**\n\n  - **Name:** Zecheng Qian\n  - **Student ID:** 3160102418\n  - **Major:** Information Engineering\n\n- **Advisor**\n\n  + WeiWei Xu, Zhejiang University\n\n    \n\n    \n\n    \n\n \n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faden-q%2Fmemory-pool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faden-q%2Fmemory-pool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faden-q%2Fmemory-pool/lists"}