BỘ NHỚ HEAP LÀ GÌ?


Khi học về con trỏ, bạn sẽ thường xuyên phải xin cấp phát và giải phóng bộ nhớ, vậy những vùng nhớ này được quản lý bởi ai và như thế nào?

Về cơ bản, khi khởi động lên, hệ điều hành sẽ nắm quyền kiểm soát toàn bộ bộ nhớ, bởi bộ nhớ có thể coi như một sân chơi chung nên phải có phải có người cầm trịch, quản lý xem chỗ nào đã có người dùng, chỗ nào còn trống, tránh việc dữ liệu của một chương trình này bị ghi đè bởi một chương trình khác.Khi bạn gọi hàm malloc, hoặc new, trình quản lý bộ nhớ sẽ tìm xem chỗ nào chưa có ai sử dụng, nó lấy một phần vừa đủ với kích thước bạn xin cấp phát, đánh dấu vùng nhớ đó đã được cấp cho chương trình (process) của bạn và trả về địa chỉ. Nhiệm vụ của bạn là lưu lại địa chỉ (vào một biến con trỏ) và chỉ sử dụng trong phạm vi đã được cấp.Khi bạn yêu cầu delete, trình quản lý bộ nhớ sẽ gỡ bỏ đánh dấu. Lúc này nếu tiếp tục sử dụng, chương trình của bạn có thể bị lỗi truy cập vùng nhớ không được phép và bị kết thúc.

ℹ️ Tất cả các thao tác xin cấp phát và giải phóng này đều làm việc trên một vùng nhớ gọi là HEAP. Ta hiểu đơn giản heap là vùng nhớ còn lại sau khi đã trừ đi các phần khác của chương trình như code, dữ liệu tĩnh, stack…Việc cấp phát/sử dụng/giải phóng một vùng nhớ luôn phải làm cẩn thận vì:

👉 Truy cập ra ngoài phạm vi được cấp phát có thể gây treo, hoặc thậm chí kết thúc chương trình.

👉 Một trong vấn đề bảo mật được phát hiện nhiều nhất là lỗi tràn bộ đệm, tức khi đọc dữ liệu, bạn cho phép đọc nhiều hơn kích thước vùng nhớ mà bạn đã xin cấp phát, khi đó phần dư ra sẽ đè lên vùng nhớ phía sau đó và làm thay đổi hành vi của chương trình. Lấy ví dụ bạn xin cấp phát 100 ký tự để nhận email từ bàn phím, ngay sau đó là 1 biến is_authenticated chứa giá trị xác định xem bạn đã đăng nhập hay chưa, khi người dùng cố ý nhập tới 101 ký tự, với ký tự cuối cùng là ‘1’, ký tự đó sẽ đè lên biến is_authenticated. Và chương trình của bạn sẽ hiểu lầm người dùng này đã đăng nhập.

👉 Các vùng nhớ đã cấp phát cần phải được giải phóng khi không dùng nữa, nếu không sẽ gây nên tình trạng memory leak, chương trình càng ngày càng phình to, sau bảy bảy bốn chín ngày có thể chiếm hết bộ nhớ và không thể hoạt động được nữa.

👉 Các vùng nhớ có thể bị phân mảnh: khi bạn xin cấp phát và giải phóng liên tục, các phần bộ nhớ trống và đã bị chiếm có thể nằm xen kẽ nhau, dẫn đến tình trạng bạn không thể xin cấp phát 1 vùng nhớ lớn dù dung lượng trống vẫn còn đủ. Mặc dù các hệ điều hành hiện đại sau này có khả năng di chuyển các vùng nhớ đó để sắp xếp lại nhưng vẫn ảnh hưởng một phần đến hiệu năng.

Một vài thông tin khác giúp bạn hiểu hơn về heap:

👉 Không có một chuẩn nào quy định ai chịu trách nhiệm quản lý bộ nhớ, do vậy đó có thể là hệ điều hành, hoặc trình runtime mà ứng dụng đang chạy trên đó (.NET, Java), hoặc do bộ thư viện runtime mà ứng dụng của bạn được biên dịch. Vậy nên cũng không có một kết quả chung nếu ứng dụng của bạn không quản lý tốt dữ liệu – bạn phải tham khảo nền tảng mà bạn đang sử dụng.

👉 .NET và Java có các trình dọn rác (garbage collector), chúng sẽ tự động giải phóng các vùng nhớ không còn được dùng (không còn biến nào chỉ tới vùng nhớ đó nữa).

👉 Về lý thuyết, bộ nhớ heap sẽ rất lớn, và hầu hết dữ liệu được xử lý sẽ được lưu trong vùng nhớ này.

👉 Dung lượng thực sự được cấp phát đôi khi lớn hơn dung lượng bạn xin cấp phát, nguyên nhân là vì ‘memory alighment’, tức một biến nên được đặt trong bộ nhớ tại một vị trí có địa chỉ là bội số của kích thước biến đó. Ví dụ 1 biến 32 bit nên được đặt tại các địa chỉ 0, 3, 7… các biến 64 bit nên được đặt tại 0, 7, 15, 23… vì khi đọc, CPU sẽ đọc theo từng khối 32 hoặc 64 bit – tùy theo kiến trúc CPU, nên nếu biến 64 bit được đặt tại địa chỉ 1, 2, 3… thì những bít sau cùng của nó sẽ nằm lọt ra khối đằng sau khiến CPU phải đọc 2 lần mới ra được giá trị.

One thought on “BỘ NHỚ HEAP LÀ GÌ?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s