Khái niệm cơ bản của một hồ bơi bộ nhớ là phải phân bổ một phần lớn bộ nhớ cho ứng dụng của bạn, và, sau đó, thay vì sử dụng đơn giản new
để yêu cầu bộ nhớ từ O/S, bạn quay lại một đoạn của giao trước đây bộ nhớ thay thế.
Để thực hiện việc này, bạn cần phải quản lý sử dụng bộ nhớ bản thân và không thể dựa vào các O/S; tức là, bạn cần phải triển khai các phiên bản new
và delete
của riêng mình và chỉ sử dụng các phiên bản gốc khi phân bổ, giải phóng hoặc có khả năng định lại kích thước nhóm bộ nhớ của riêng bạn.
Cách tiếp cận đầu tiên là xác định Lớp của riêng một gói bộ nhớ và cung cấp các phương thức tùy chỉnh thực hiện ngữ nghĩa của new
và delete
, nhưng lấy bộ nhớ từ nhóm được phân bổ trước. Hãy nhớ rằng, hồ bơi này là không có gì nhiều hơn một khu vực bộ nhớ đã được phân bổ bằng cách sử dụng new
và có một kích thước tùy ý. Phiên bản new
/delete
trả lại của hồ bơi. lấy con trỏ. Phiên bản đơn giản nhất có thể trông giống như mã C:
void *MyPool::malloc(const size_t &size)
void MyPool::free(void *ptr)
Bạn có thể thêm tiêu đề này với mẫu để tự động thêm chuyển đổi, ví dụ:
template <typename T>
T *MyClass::malloc();
template <typename T>
void MyClass::free(T *ptr);
Chú ý rằng, nhờ vào các đối số mẫu, lập luận size_t size
thể được bỏ qua kể từ khi trình biên dịch cho phép bạn gọi sizeof(T)
trong malloc()
.
Trả về một con trỏ đơn giản có nghĩa là hồ bơi của bạn chỉ có thể phát triển khi có bộ nhớ liền kề và chỉ thu nhỏ nếu bộ nhớ trong vùng ở "đường viền" của nó không được lấy. Cụ thể hơn, bạn không thể di chuyển hồ bơi vì điều đó sẽ làm mất hiệu lực tất cả các con trỏ hàm malloc của bạn trả lại.
Cách khắc phục giới hạn này là trả lại con trỏ cho con trỏ, tức là trả lại T**
thay vì chỉ đơn giản là T*
. Điều đó cho phép bạn thay đổi con trỏ bên dưới trong khi phần người dùng phải đối mặt vẫn giữ nguyên. Ngẫu nhiên, điều đó đã được thực hiện cho NeXT O/S, nơi nó được gọi là "xử lý". Để truy cập vào nội dung của tay cầm, người ta phải gọi (*handle)->method()
hoặc (**handle).method()
. Cuối cùng, Maf Vosburg đã phát minh ra một toán tử giả khai thác toán tử ưu tiên để loại bỏ cú pháp (*handle)->method()
: handle[0]->method();
Cú pháp này được gọi là sprong operator.
Những lợi ích của hoạt động này là: Thứ nhất, bạn tránh được những chi phí của một cuộc gọi thông thường để new
và delete
, và thứ hai, hồ bơi bộ nhớ của bạn đảm bảo rằng một đoạn tiếp giáp bộ nhớ được sử dụng bởi ứng dụng của bạn, ví dụ, nó tránh bộ nhớ phân mảnh và do đó tăng số lần truy cập bộ nhớ cache CPU.
Vì vậy, về cơ bản, một nhóm bộ nhớ cung cấp cho bạn tốc độ bạn đạt được với nhược điểm của mã ứng dụng phức tạp hơn. Nhưng sau đó một lần nữa, có một số hiện thực của các hồ bơi bộ nhớ được chứng minh và có thể chỉ đơn giản được sử dụng, chẳng hạn như boost::pool.
Hãy xem [boost :: pool] (http://www.boost.org/doc/libs/1_58_0/libs/pool/doc/html/index.html) – rds504
Xem thêm: http: // stackoverflow.com/questions/16378306/c11-memory-pool-design-pattern – NathanOliver
Có thể điều này sẽ giúp: [Quản lý bộ nhớ] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa366779%28v = vs.85% 29.aspx) – Zero