12/08/2018, 15:53

[Java Core] Garbage Collection

Khi chạy một chương trình, có vô số object được khởi tạo như String, Interger, ArrayList, Map … và các defined object được tạo ra và lưu trữ trong memory lúc runtime. Sẽ có một vấn đề xảy ra đối với memory lúc này. Khi memory đầy, JVM phải loại bỏ một vài objects để lấy chỗ khởi tạo các ...

Khi chạy một chương trình, có vô số object được khởi tạo như String, Interger, ArrayList, Map … và các defined object được tạo ra và lưu trữ trong memory lúc runtime. Sẽ có một vấn đề xảy ra đối với memory lúc này. Khi memory đầy, JVM phải loại bỏ một vài objects để lấy chỗ khởi tạo các object mới. Thế nhưng làm sao JVM biết được nó nên loại bỏ object nào ?

Garbage Collection sẽ giải quyết vấn đề này, có một vài ý chính để mô tả garbage collection như sau

  • Mục đích của garbage collection là loại bỏ các object nào không được gọi đến
  • Các object có thể được garbage collection kể cả khi nó đang gọi đến các object khác

Chúng ta sẽ cùng tìm hiểu ý nghĩa của 2 ý trên Nếu một object không được gọi đến, nó có nghĩa là không có một thread nào đang truy cập đến nó thông qua reference variable sử dụng trong chương trình. Ta hãy xem đoạn code sau

Object obj = new Object();

  • Object là kiểu của reference variable obj
  • Một reference variable (biến) xác định việc trỏ đến một Object
  • new Object(); sẽ tạo 1 object mới trong memory
  • Reference variable obj lúc này sẽ trỏ vào object đó

Khi ta viết obj = null; sẽ hủy kết nối của obj đến object trong memory. Lúc này object trong memory sẽ không có reference nào trỏ đến nó nữa. Lúc này thì object sẽ phù hợp để garbage collection. Tuy nhiên nếu một object chứa một reference tới một object khác thì sẽ thế nào ? Ta có ví dụ sau : Ta có 3 object Room, Door, DoorKnob - Một Room có một door - Một Door có một doorknob

public class DoorKnob{
}
public class Door{

	private DoorKnob knob = new DoorKnob();
    
	public DoorKnob getKnob() {
		return knob;
	}
    
	public void setKnob(DoorKnob knob) {
		this.knob = knob;
	}
}
public class Room {
 
	private Door door = new Door();
 
	public Door getDoor() {
		return door;
	}
 
	public void setDoor(Door door) {
		this.door = door;
	}
 
}

Ta đã có 3 class, Room có reference đến Door và Door có reference đến DoorKnob

public class Test {
 
	public static void main(String[] args){
 
		Door door = new Door();
		Room room = new Room();

	}
 
}

Khi Door door = new Door(); được thực thi, object Door được khởi tạo và variable door reference đến nó. Vì một door có một doorknob cho nên ngay khi object Door được khởi tạo, object DoorKnob cũng được tạo ra và nó được variable trong class Door reference đến nó. Hãy ghi nhớ những kí hiệu này

Khi dòng Room room = new Room(); được thực thi, scenario sẽ như dưới đây

Bây giờ nếu như ta set door phía trên cho room bằng room.setDoor(door); thì object door được variable room.door trong class Room reference đến sẽ mất và nó không còn variable nào reference đến nó nữa. Ta có thể test xem object door trong room hiên giờ đã thay đổi hay chưa bằng code sau

public static void main(String[] args){

		Door door = new Door();
		Room room = new Room();
		System.out.println(room.getDoor());
		System.out.println(door);
		room.setDoor(door);
		System.out.println(room.getDoor());

	}

Output

com.gc.Door@45bab50a
com.gc.Door@64c3c749
com.gc.Door@64c3c749

Ta có output là hashcode của object đó, giá trị hashcode khác nhau có nghĩa là object khác nhau Bây giờ ta thử loại bỏ reference đến object room bằng cách sau

room = null;
System.out.println(room.getDoor());

Nếu chạy đoạn code này tất nhiên sẽ là NullPointerException bời vì room đã null và object room đã phù hợp để garbage collection. Tuy nhiên ta vẫn có thể truy cập đến object door thông qua variable reference door System.out.println(door); Ta tóm tắt lại quá trình của ví dụ này như sau

  • Door door = new Door() tạo 1 và 2 và door refer đến 1
  • Room room = new Room() tạo 3,4 và 5 và room refer đến 3
  • room.setDoor(door) làm 3 mất kết nối đến 4 nhưng 4 vẫn nối đến 5
  • room = null; làm room mất kết nối đến 3 nhưng 3 vẫn nối đến 1
  • Ta không thể truy cập đến 1 qua 3 được nữa vì ta không thể truy cập đến 3
  • Ta có thể truy cập thằng đến 1 và 2 thông qua 1

Bây giờ ta đã có câu trả lời cho câu hỏi các object nào sẽ phù hợp để garbage collection đó chính là 3, 4 và 5 bời chúng không có môt kết nối nào đến thông qua các reference variable. Hy vọng ví dụ trên đây sẽ giúp các bạn hiểu hơn về ý tưởng của garbage collection. Nguồn : link

0