Java: Quản lý bộ nhớ trong Java

Các bộ nhớ bao gồm hai thành phần cụ thể là Stack và Heap. Stack là một vùng nhớ trong đó lưu trữ các tham chiếu đối tượng và thông tin phương thức bao gồm: các tham số của một phương thức và các biến cục bộ. Heap là vùng nhớ dùng để cấp phát vùng nhớ động. Điều này có nghĩa là, các đối tượng Java được cấp phát vùng nhớ vật lý trên Heap lúc thực thi (runtime). Việc cấp phát vùng nhớ đươc thực hiện mỗi khi JVM thực thi toán tử new.

Vùng nhớ Heap sẽ tăng dần kích thước lên mỗi khi các đối tượng được cấp phát vùng nhớ vật lý. Vì thế, JVM cung cấp giải pháp thu dọn rác để giải phóng vùng nhớ bằng cách hủy những đối tượng mà không còn được dùng đến trong Java. Với cách thức này thì vùng nhớ trong Heap sẽ được tái sử dụng cho các đối tượng khác.

Khi làm việc với các kiểu dữ liệu nguyên thủy, giá trị của một biến có thể được gán cho biến khác bằng cách sử dụng toán tử gán (=).

Ví dụ,

int a = 10;
int b = a;

Câu lệnh b = a; sẽ tiến hành sao chép giá trị từ biến a và lưu trữ vào trong biến b.

Hình sau đây cho thấy thao tác gán một giá trị từ biến này sang biến khác:

Sao chép dữ liệu trong kiểu dữ liệu nguyên thủy

Xét câu lệnh Rectangle objRect1;objRect1 được gọi là biến tham chiếu đối tượng vì nó lưu trữ tham chiếu (địa chỉ vùng nhớ) của đối tượng. Giá trị của các kiểu dữ liệu nguyên thủy có thể được sao chép, thì tương tự, giá trị lưu trữ trong một biến tham chiếu đối tượng cũng có thể được sao chép tới một biến tham chiếu khác. Vì Java là một ngôn ngữ định kiểu mạnh, nên tất cả các biến tham chiếu đều phải có cùng kiểu. Nói cách khác, tất cả các biến tham chiếu trong trường hợp này phải thuộc về cùng một lớp.

Đoạn mã dưới đây thể hiện việc gán tham chiếu của một đối tượng cho một đối tượng khác.

public class TestObjectReferences {
  public static void main(String[] args) {
    /* Tạo một đối tượng có kiểu Rectangle và lưu trữ
    * tham chiếu của nó vào biến tham chiếu đối tượng là objRec1
    */
    Rectangle objRec1 = new Rectangle(10, 20);
    // Khai báo một biến tham chiếu kiểu Rectangle
    Rectangle objRec2;
    // Gán giá trị của objRec1 cho objRec2
    objRec2 = objRec1;
    System.out.println(“\nChi tiet cua Rectangle1”);
    System.out.println(“===================”);
    /* Gọi phương thức hiển thị các giá trị của
    * các biến thể hiện cho đối tượng objRec1
    */

    objRec1.displayDimensions();
    System.out.println(“\nChi tiet cua Rectangle2”);
    System.out.println(“===================”);
    objRec2.displayDimensions();
  }
}

Đoạn mã trên tạo hai biến tham chiếu đối tượng là objRec1 và objRec2objRec1 trỏ tới đối tượng mà được cấp phát vùng nhớ và được khởi tạo cho các giá trị 10 và 20 thông quan hàm tạo, còn objRec2 không trỏ tới đối tượng nào. Với câu lệnh objRec2 = objRec1; thì tham chiếu được lưu trữ trong objRec1 sẽ được sao chép vào objRec2, và nằm giữa các biến đã được tạo trong stack mà không ảnh hưởng đến các đối tượng được tạo trên Heap.

Hình dưới đây cho thấy việc gán tham chiếu của câu lệnh objRec2 = objRec1; được thực hiện trên Stack.

java1-sao-chep-tham-chieu-tren-stack