Bài 1. Bạn đã biết cách tổ chức lưu trữ dữ liệu của một chương trình Java trên bộ nhớ máy tính?

Để bắt đầu cho series này, tớ sẽ đi đến phần căn bản nhất, đó là cách mà một chương trình Java lưu trữ dữ liệu trên bộ nhớ máy tính.
Khi một chương trình Java được thực thi, nó sẽ yêu cầu hệ điều hành cấp phát một không gian trên bộ nhớ để lưu trữ toàn bộ dữ liệu và thông tin của nó.

Sau đó, nó sẽ chia vùng không gian đó thành 4 vùng nhớ (memory segment) để lưu trữ. Để dễ hiểu thì các bạn xem hình ảnh bên dưới nhé :)
1
  1. Vùng nhớ code (code segment), theo như tên gọi của nó, tất cả mã chương trình (machine code) được lưu ở đây khi chương trình được thực thi.
  1. Vùng nhớ data (data segment), đây là nơi lưu trữ những dữ liệu chung của chương trình như các biến static, constant,… những biến dữ liệu mà được sinh ra khi chương trình bắt đầu thực thi và chỉ được giải phóng khi chương trình kết thúc.
  1. Vùng nhớ stack (stack segment), đây sẽ là nơi lưu trữ các biến thuộc nhóm kiểu dữ liệu cơ sở (primitive data type như là boolean, int, char,…) và địa chỉ của ô nhớ (memory address).
Tại sao gọi là vùng nhớ stack? Bởi vì dữ liệu ở đây chia theo các nhóm gọi là stack frame, và mỗi stack frame sẽ được lưu vào vùng nhớ stack theo cơ chế Last-in-first-out (LIFO) như một stack.
Vậy, stack frame (SF) là gì? Nó là nơi lưu trữ toàn bộ các biến của một phương thức (method), mỗi phương thức được thực thi sẽ tạo ra một SF. Xem ví dụ bên dưới để hiểu rõ hơn nhé :P
Ở chương trình dưới ta có 3 method: methodA(), methodB() và main:

public static void methodA(){
int a = 10;
System.out.println(a);
}
public static void methodB(){
int b = 20;
System.out.println(b);
methodA();
}
public static void main(String[] args){
int c = 30;
methodB();
}

Khi chương trình này thực thi, nó sẽ tạo ra 3 SF và push vào vùng nhớ stack theo thứ tự nó được gọi: main, methodB, methodA.2
Với phương thức main() ta có biến c = 30 nên giá trị 30 này sẽ được lưu trữ ở SF main, và biến c này cũng sẽ có phạm vi sử dụng trong phương thức main() mà thôi. (Xem hình bên)
Tương tự với các phương thức methodB() và methodA(), ta cũng sẽ có các biến b và a tương ứng. Biến b sẽ được lưu trữ ở SF methodB và chỉ có phạm vi sử dụng ở đó, tương tự cho biến a cũng sẽ được lưu trữ ở SF methodA và chỉ có phạm vi sử dụng ở đây thôi nhé.
Khi methodA() thực thi xong, SF methodA sẽ được pop ra khỏi vùng nhớ stack, biến a (với giá trị là 10) đồng thời cũng được giải phóng. Sau đó SF methodB sẽ được pop, biến b được giải phóng và cuối cùng là tới SF main và biến c.

  1. Vùng nhớ heap (heap segment), đây là nơi lưu trữ tất cả các đối tượng (object) được sinh ra trong thời gian thực thi chương trình (run time).

Với vùng nhớ Code và Data, khi chương trình thực thi sẽ cấp phát một không gian có kích thước không đổi.
Còn đối với vùng nhớ Stack và Heap, kích thước của nó sẽ thay đổi (hoặc mở rộng khi tạo thêm biến hoặc đối tượng, hoặc thu hẹp khi một biến hoặc đối tượng được giải phóng) và nếu cần mở rộng thêm, nó sẽ lấy không gian từ Free memory. (Xem lại hình đầu tiên nhé :P )3
Ngoài ra, trong bộ nhớ máy tính, mỗi ô nhớ sẽ được đánh địa chỉ để xác định chính xác vị trí của nó trong bộ nhớ. Vì vậy trong mỗi ô nhớ sẽ bao gồm 2 thành phần là Value và Addressnhư hình vẽ.


Chào đón các bạn trong bài viết tiếp theo nhé! :P

Nhận xét