Bạn có thể muốn lùi lại và xem những mô hình hiện có đến từ đâu và tại sao. Khi một quy trình được tạo, nó chỉ được cung cấp một vùng lưu trữ phẳng được lập chỉ mục đơn giản từ 0 đến N. Bởi vì vùng lưu trữ này (nói về RAM ở đây) được hỗ trợ bởi một phần cứng chuyên dụng và một số chất bán dẫn lạ mắt, nó xảy ra khá nhanh, nhưng nó không phải là người duy nhất thuộc loại này. Các thiết bị khác như ổ cứng về cơ bản là giống nhau, không gian phẳng có thể định địa chỉ bằng một chỉ mục, nhưng nhiều đơn đặt hàng có cường độ chậm hơn.
Lý do tại sao "một đống" tồn tại là bởi vì nó sẽ không thực tế đối với mỗi ứng dụng để cố gắng tự quản lý việc sử dụng RAM. Quay trở lại vào ban ngày, đó chính xác là cách nó đã xảy ra, các lập trình viên đã lên kế hoạch trước thời hạn chính xác từng vị trí RAM sẽ được sử dụng cho mục đích gì. Khi phần mềm trở nên phức tạp hơn, ai đó đã nói, sẽ không hay nếu tôi có thể đi đến một hộp đen nào đó và nói "Tôi cần 10 byte vậy gimme" và không phải lo lắng về tất cả các chi tiết phức tạp về vị trí và 10 byte đó như thế nào đến từ hoặc làm thế nào họ được khai hoang. Đó là một đống, không thực sự trở nên cơ bản hơn thế.
Mỗi khi một luồng được tạo, có một số cấu trúc dữ liệu (và một ngăn xếp), được thu nhận bằng cách sử dụng cùng một "thao tác gimme" mà tôi vừa mô tả. Một ngăn xếp chỉ được sử dụng phổ biến vì nó phù hợp hoàn hảo với các khung ngăn xếp cuộc gọi chức năng và bản chất LIFO của chúng. Về lý thuyết, mỗi lệnh gọi hàm và biến cục bộ có thể được phân bổ trên heap, nhưng điều đó đơn giản là quá đắt, so với chỉ một vài hướng dẫn lắp ráp cần có để cập nhật thanh ghi con trỏ ngăn xếp (ESP trên x86).
Lưu trữ cục bộ luồng (TLS) cũng được xây dựng trên đỉnh heap. Khi một luồng được tạo, như một phần của chuyến đi đến vùng heap để phân bổ bộ nhớ cho các cấu trúc quản lý, một không gian riêng cho TLS cũng được phân bổ từ vùng heap.
Vì vậy, cuối cùng, tất cả những gì bạn thực sự có là một cấp phát bộ nhớ chung (tức là heap) và mọi thứ khác là một hình thức chuyên biệt trên đó. Nói cách khác, nếu bạn sẵn sàng từ bỏ một số khía cạnh của "Tôi muốn phân bổ bao nhiêu (hoặc ít) như tôi muốn, hãy giữ nó miễn là tôi muốn và miễn phí bất cứ khi nào tôi muốn", bạn có thể thoát khỏi giao dịch tắt phân bổ heap chung cho một mô hình khác cung cấp tốc độ nhưng với chi phí của một số hạn chế khác.
Lấy chồng. Nó cực kỳ nhanh khi so sánh với heap, nhưng hai sự đánh đổi là 1) bạn không kiểm soát khi bộ nhớ được giải phóng; thay vào đó một khi chức năng thoát, bất cứ thứ gì bạn phân bổ đều biến mất và 2) vì các ngăn xếp thường bị giới hạn về kích thước, bạn nên cẩn thận phân bổ số lượng lớn dữ liệu trực tiếp trên ngăn xếp.
Một loại "mô hình bộ nhớ" khác là Trình quản lý bộ nhớ ảo (VMM) được cung cấp bởi mọi hệ điều hành chính thông qua các cuộc gọi hệ thống. VMM rất giống với heap theo nghĩa bạn có thể yêu cầu bất kỳ dung lượng bộ nhớ nào và giữ nó miễn là bạn muốn. Tuy nhiên, hạn chế là bạn chỉ có thể phân bổ bộ nhớ theo bội số kích thước trang (ví dụ 4KB) nên việc sử dụng VMM trực tiếp sẽ gây ra nhiều chi phí trong một ứng dụng thông thường thường phân bổ 8-24 byte mỗi lần. Trong thực tế, gần như mọi triển khai heap đều được xây dựng dựa trên VMM đặc biệt cho các mục đích cho phép phân bổ chặn nhỏ rất chung chung, không chuyên biệt, nhỏ . Heap chuyển đến VMM bất cứ khi nào nó cần thêm bộ nhớ và sau đó loại bỏ nhiều phần nhỏ của bộ nhớ đó cho ứng dụng.
Nếu bạn có một ứng dụng, có nhu cầu phân bổ các khối lớn, bạn có thể cân nhắc đến trực tiếp VMM, mặc dù một số heap có câu lệnh if bên trong malloc () và nếu kích thước khối lớn hơn ngưỡng nào đó, chúng chỉ cần chuyển đến VMM cho bạn.
Một hình thức phân bổ khác thay vì trực tiếp sử dụng heap, sẽ là pool. Một hồ bơi là một phân bổ chuyên biệt trong đó tất cả các khối có cùng kích thước. Các hồ bơi (giống như stack và TLS) được xây dựng trên đỉnh heap hoặc VMM. Bể bơi rất hữu ích ở những nơi bạn phân bổ rất nhiều (hàng triệu) vật thể nhỏ, có cùng kích thước. Hãy suy nghĩ một dịch vụ mạng xử lý các yêu cầu đến. Mỗi yêu cầu máy khách có thể dẫn đến cấu trúc byte N giống nhau được phân bổ để xử lý yêu cầu đó. Sự đánh đổi với việc sử dụng các nhóm là mỗi nhóm chỉ xử lý một kích thước khối (nhưng bạn có thể tạo nhiều nhóm). Ưu điểm của pool là bởi vì tất cả các đối tượng có cùng kích thước, nó không yêu cầu logic phức tạp. Thay vào đó, bất cứ khi nào bạn cần một khối mới, nó sẽ cung cấp cho bạn khối mới được giải phóng gần đây.
Và cuối cùng, hãy nhớ rằng điều ổ cứng tôi đã đề cập lên trên. Bạn có thể có một mô hình bộ nhớ hoạt động giống như một hệ thống tệp và sao chép cùng một ý tưởng về các mục nhập thư mục và các nút i để cho phép bạn phân bổ phân cấp các khối dữ liệu trong đó mỗi khối dữ liệu được xử lý theo một đường dẫn. Đó chính xác là những gì tmpfs làm.
Ngoài những thứ tôi đã đề cập, tôi chắc chắn còn có những mô hình chuyên dụng khác, nhưng cuối cùng vì mọi thứ đều dựa trên không gian địa chỉ phẳng (đó là cho đến khi một số genuis xuất hiện một loại kỳ lạ - một không gian không phẳng $$ ), tất cả quay trở lại với cấp phát "gimme" chung đó là VMM hoặc heap.