Search…

Memory Segment

Nguyễn Hữu HiếuNguyễn Hữu Hiếu
18/09/20204 min read
Tìm hiểu về Memory Segment, các vùng nhớ cơ bản cho 1 chương trình C++: Stack Segment, Heap Segment, Data Segment, Code Segment.

Biến là một thể hiện trừu tượng của vùng nhớ, dữ liệu và cả hàm cũng được lưu trữ trong bộ nhớ. Để có thể làm việc hiệu quả hơn với bộ nhớ, cần nắm bắt những đặc điểm của chúng.

Tổng quan

Khi một chương trình C++ thực thi, có rất nhiều vùng nhớ có thể được sử dụng, nhưng trong đó có 4 vùng nhớ cần lưu ý:

Memory segments.
Memory segment của chương trình

Code Segment

Ngôn ngữ lập trình như C/C++, Java và ngôn ngữ máy tính là 2 ngôn ngữ hoàn toàn khác nhau. Khi một chương trình được biên dịch, nó sẽ được chuyển thành các mã máy chỉ bao gồm mã nhị phân 0 và 1.

Đây là vùng nhớ chứa mã máy để thực thi chương trình. Cũng có thể tưởng tượng rằng đây là vùng nhớ lưu trữ câu chuyện kể về chương trình cho máy tính hiểu và người dịch truyện là trình biên dịch. Tuy nhiên, đây là vùng nhớ mang thuộc tính read only nhằm ngăn chặn việc vô tình thay đổi những chỉ thị trong vùng nhớ này khi chương trình thực thi.

Data Segment

Đây là nơi lưu trữ những dữ liệu tĩnh: biến có phạm vi global hoặc các biến static. Thường được chia làm 2 vùng nhỏ hơn là Initialized Data SegmentUninitialized Data Segment.

Initialized Data Segment chứa giá trị của những biến global và static và được khởi tạo giá trị sớm. Vùng nhớ này có thể mang thuộc tính read only, hoặc read-write tùy thuộc vào cách mà bạn khởi tạo biến này. Chẳng hạn tôi có đoạn chương trình sau:

const char* _string = "DataSegment_stdio_vn";

int main()
{
	return 0;
}

Lúc này, biến _string sẽ được lưu trong Initialized Data Segment với thuộc tính read-write, còn chuỗi DataSegment_stdio_vn sẽ được lưu trong vùng nhớ đó nhưng với thuộc tính read only.

Uninitialized Data Segment (hay còn gọi là BSS Segment) là vùng nhớ lưu trữ những biến global và static được khởi tạo với giá trị bằng 0 hay chưa được khởi tạo. Tôi có ví dụ sau:

int global_var_1;

int main()
{
	static int static_var_2;
	return 0;
}

Khi này, biến global_var_1static_var_2 sẽ được lưu trong Uninitialized Data Segment và có giá trị là 0.

Stack Segment

Stack có thể được biết đến như một cấu trúc First In – Last Out (FILO). Trong bộ nhớ máy tính, Stack là một phân khúc lưu trữ những biến tạm thời được tạo ở trong phương thức (kể cả hàm main()). Phân khúc này được CPU quản lý và tối ưu khá chặt chẽ. Khi một biến được khai báo trong hàm, nó sẽ được push vào Stack, khi hàm đó kết thúc, toàn bộ những biến đã được đẩy vào trong stack sẽ được pop và giải phóng. Vì đặc tính này cho nên biến lưu trên Stack mang tính chất local.

Khi sử dụng biến lưu trên Stack, không cần quan tâm đến việc cấp phát và thu hồi biến đó. Ngoài ra, truy cập ở phân khúc Stack sẽ nhanh hơn một chút so với Heap nhưng bù lại phân khúc này lại có kích thước có giới hạn tùy vào cấu hình với trình biên dịch.

Heap Segment

Heap là phân khúc bộ nhớ cấp phát tự do. Tuy nhiên nó lại không được quản lý tự động, phải tự quản lý toàn bộ những vùng nhớ đã cấp phát trên Heap, nếu không còn sử dụng nữa mà không tự thu hồi sẽ gây ra hiện tượng rò rỉ bộ nhớ - memory leak. Để cấp phát vùng nhớ trên Heap, có thể dùng malloc() – tức là memory allocation hoặc new. Để thu hồi vùng nhớ bạn có thể dùng free() – tức là memory deallocation hoặc delete. Dữ liệu trên Heap do lập trình viên tự quản lý, do đó, nó có thể được sử dụng giữa các phương thức với nhau.

Lời kết

Hiểu về tổ chức bộ nhớ của chương trình rất ý nghĩa trong việc nắm rõ cách thức chương trình cấp phát và thu hồi bộ nhớ, giúp có định hướng tối ưu bộ nhớ của chương trình nên đây là kiến thức cần tìm hiểu chuyên sâu.

IO Stream

IO Stream Co., Ltd

developer@iostream.co
383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024