Phân mảnh bộ nhớ là khái niệm tương tự như phân mảnh đĩa: nó đề cập đến không gian bị lãng phí vì các khu vực sử dụng không được đóng gói đủ chặt chẽ với nhau.
Giả sử với một ví dụ đồ chơi đơn giản rằng bạn có mười byte bộ nhớ:
| | | | | | | | | | |
0 1 2 3 4 5 6 7 8 9
Bây giờ, hãy phân bổ ba khối ba byte, tên A, B và C:
| A | A | A | B | B | B | C | C | C | |
0 1 2 3 4 5 6 7 8 9
Bây giờ giải quyết khối B:
| A | A | A | | | | C | C | C | |
0 1 2 3 4 5 6 7 8 9
Bây giờ điều gì xảy ra nếu chúng ta cố gắng phân bổ một khối D bốn byte? Chà, chúng tôi có bốn byte bộ nhớ miễn phí, nhưng chúng tôi không có bốn byte bộ nhớ liền kề , vì vậy chúng tôi không thể phân bổ D! Đây là việc sử dụng bộ nhớ không hiệu quả, vì chúng tôi đã có thể lưu trữ D, nhưng chúng tôi không thể. Và chúng tôi không thể di chuyển C để tạo khoảng trống, vì rất có thể một số biến trong chương trình của chúng tôi đang trỏ đến C và chúng tôi không thể tự động tìm và thay đổi tất cả các giá trị này.
Làm thế nào để bạn biết đó là một vấn đề? Chà, dấu hiệu lớn nhất là kích thước bộ nhớ ảo của chương trình của bạn lớn hơn đáng kể so với dung lượng bộ nhớ bạn thực sự sử dụng. Trong một ví dụ trong thế giới thực, bạn sẽ có nhiều hơn mười byte bộ nhớ, do đó, D sẽ chỉ được cấp phát bắt đầu một byte 9 và các byte 3-5 sẽ không được sử dụng trừ khi sau đó bạn đã phân bổ thứ gì đó dài hơn hoặc nhỏ hơn ba byte.
Trong ví dụ này, 3 byte không phải là một sự lãng phí hoàn toàn, nhưng hãy xem xét một trường hợp bệnh lý hơn trong đó hai phân bổ của một vài byte, ví dụ, cách nhau mười megabyte trong bộ nhớ và bạn cần phân bổ một khối có kích thước 10 megabyte + 1 byte. Bạn phải yêu cầu HĐH cho bộ nhớ ảo hơn mười megabyte để làm điều đó, mặc dù bạn chỉ cần một byte để có đủ dung lượng.
Bạn phòng tránh bằng cách nào? Các trường hợp xấu nhất có xu hướng phát sinh khi bạn thường xuyên tạo và phá hủy các vật thể nhỏ, vì điều đó có xu hướng tạo ra hiệu ứng "pho mát Thụy Sĩ" với nhiều vật thể nhỏ cách nhau bởi nhiều lỗ nhỏ, khiến chúng không thể phân bổ các vật thể lớn hơn trong các lỗ đó. Khi bạn biết bạn sẽ thực hiện việc này, một chiến lược hiệu quả là phân bổ trước một khối bộ nhớ lớn làm nhóm cho các đối tượng nhỏ của bạn, sau đó quản lý thủ công việc tạo các đối tượng nhỏ trong khối đó, thay vì cho phép bộ cấp phát mặc định xử lý nó.
Nói chung, bạn càng phân bổ ít, bộ nhớ càng ít bị phân mảnh. Tuy nhiên, STL giải quyết vấn đề này khá hiệu quả. Nếu bạn có một chuỗi sử dụng toàn bộ phân bổ hiện tại của nó và bạn nối thêm một ký tự cho chuỗi đó, thì nó không chỉ phân bổ lại cho độ dài hiện tại của nó cộng với một chuỗi, nó nhân đôi độ dài của nó. Đây là một biến thể của chiến lược "nhóm phân bổ nhỏ thường xuyên". Chuỗi đang chiếm một phần lớn bộ nhớ để có thể xử lý hiệu quả với các mức tăng nhỏ lặp đi lặp lại mà không thực hiện các phân bổ nhỏ lặp đi lặp lại. Trên thực tế, tất cả các container STL đều làm điều này, vì vậy nhìn chung bạn sẽ không cần phải lo lắng quá nhiều về sự phân mảnh gây ra bởi các container STL tự động phân bổ lại.
Mặc dù tất nhiên STL container không hồ bơi bộ nhớ giữa mỗi khác, vì vậy nếu bạn đang đi để tạo ra nhiều container nhỏ (chứ không phải một vài container mà có được thay đổi kích cỡ thường xuyên), bạn có thể phải quan tâm mình với việc ngăn ngừa sự phân mảnh trong cùng một cách bạn sẽ cho bất kỳ đối tượng nhỏ thường xuyên tạo, STL hay không.