Hình 6.8. Kết quả thực hiện ví dụ 6.8
6.13. Thu dọn rác
Thu dọn “rác” (Garbage collection) cải tạo hoặc làm trống bộ nhớ đã cấp cho các đối tượng mà các đối tượng này không sử dụng trong thời gian dài. Trong ngôn ngữ lập trình hướng đối tượng khác như C++, lập trình viên phải tự giải phóng. Thất bại trong việc giải phóng bộ nhớ có thể gây ra một số hậu quả. Java tự động tiến hành thu dọn rác để cung cấp giải pháp cho vấn đề này. Một đối tượng trở nên thích hợp cho sự dọn rác nếu không có tham chiếu đến nó, hoặc nếu nó được gán bằng null.
Trình thực thi dọn rác là một luông chạy ngầm (deamon) co mức ưu tiên thấp. Ta có thể gọi phương thức gc() của thể nghiệm để dọn rác. Tuy nhiên, bạn không thể dự đoán hoặc bảo đảm rằng sự dọn rác sẽ thực thi ngay sau đó.
Sử dụng câu lệnh sau để tắt đi sự dọn rác trong ứng dụng: Java –noasyncgc ….
Nếu chúng ta tắt đi sự dọn rác, chương trình hầu như chắc chắn rằng bị treo do thiếu bộ nhớ.
Phương thức finalize()
Java cung cấp một phương pháp để làm sạch rác trước khi một luồng, chương trình kết thúc. Điều này tương tự như phương thức Destructor của C++
Có thể bạn quan tâm!
- Trạng Thái Của Luồng Và Các Phương Thức Của Lớp Thread
- Kết Quả Hiển Thị Của Ví Dụ 6.5 Không Có Sự Đồng Bộ
- Lập trình Java - 32
Xem toàn bộ 267 trang tài liệu này.
Phương thức finalize(), nếu có, sẽ được thực thi trên mỗi đối tượng, trước khi sự dọn rác thực hiện.
Câu lệnh của phương thức finalize() như sau: protected void finalize() throws Throwable
Tham chiếu không phải là rác; chỉ các đối tượng mới gọi là rác Ví du:
Object a = new Object();
Object b = a; a = null;
Ở đây, nó sẽ sai khi nói rằng “b” là một đối tượng. Nó chỉ là một tham chiếu. Hơn nữa, trong đoạn mã trích trên mặc dù “a‟ được đặt là rỗng, nó không thể được dọn, bởi vì nó vẫn còn có một tham chiếu b đến nó. Vì thế “a” vẫn còn với truy cập được, thật vậy, nó vẫn còn có phạm vi sử dụng trong phạm vi chương trình. Ở đây, nó sẽ không được dọn.
Tuy nhiên, trong ví dụ cho dưới đây, giả định rằng không có tham chiếu đến “a” tồn tại, đối tượng “a” trở nên thích hợp cho việc dọn rác.
Object a = new Object();
…
…
…
a = null;
Một ví dụ khác:
Object m = new Object(); Object m = null;
Đối tượng được tạo ra ban đầu trở thành đối tượng cần dọn cho bộ dọn rác
Object m = new Object(); m = new Object();
Bây giờ, ban đầu sẽ được dọn, và một đối tượng mới tham chiếu bởi “m” đang tồn tại.
Bạn có thể chạy phương thức gc() (garbage collection), nhưng không bảo đảm rằng nó sẽ chạy.
Ví dụ 6.9: điển hình cho gc().
class GCDemo
{
public static void main(String args[])
{
int i; long a; ,
Runtime r=Runtime.getRuntime(); long valuesD =new long[200];
System.out.println("Amount of free memory is" + r.freeMemory()); r.gc();
System.out.println("Amount of free memory after garbage collection is "
+ r.freeMemory());
for (a=10000,i=0;i<200;a++,i++)
{
values[i] =new long(a);
}
System.out.println("Amount of free memory after creating the array " + r.freeMemory());
for (i=0;i<200;i++)
{
values[i] =null;
}
System.out.println("Arnount of free memory after garbage collection is " + r.freeMemory());
}
}
Chúng ta khai một mảng gồm 200 phần tử, trong đó kiểu dữ liệu là kiểu long. Trước khi mảng được tạo ra, chúng ta phải xem lượng bộ nhớ trống, và hiển thị nó. Rồi thì chúng ta gọi phương thức gc() của đối tượng Runtime hiện thời. Điều này không chắc sẽ thực thi dọn rác ngay. Rồi chúng ta tạo ra mảng, và gán giá trị cho các phần tử của mảng. Điều này sẽ giảm bớt số lượng bộ nhớ trống. Để làm các phần tử mảng trở thành đối tượng cho bộ thu nhặt rác ta gán chúng bằng null. Cuối cùng, chúng ta sử dụng phương thức gc() để gọi bộ dọn rác lần nữa.
Kết quả xuất ra màn hình của chương trình trên như sau:
Hình 6. 9. Kết quả chạy ví dụ 6.9
Câu hỏi và bài tập chương 6
1. Viết một chương trình mà hiển thị một sự đếm lùi từng giây cho đến không, như hình sau:
Ban đầu, số 300 sẽ được hiển thị. Giá trị sẽ được giảm dần cho đến 1 đến khi đạt giá trị 0. Giá trị sẽ được trả lại 300 một lần nữa giảm đến trở thành 0.
2. Viết một chương trình mà hiển thị như hình dưới đây:
Tạo 3 luồng và một luồng chính trong “main”. Thực thi mỗi luồng như một chương trình. Khi chương trình kết thúc, các câu lệnh thoát cho mỗi luồng sẽ được hiển thị. Sử dụng kỹ thuật xử lý ngoại lệ.
3. Sử dụng Java Awt, Java Applet, và Thread viết chương trình vẽ một đoạn thẳng màu đỏ trên nền đen chuyển động quy trung quanh một tâm cố định theo mẫu ở hình sau:
4. Sử dụng Java Awt, Java Applet, Thread vẽ ra màn hình dòng chữ “WellCome” màu magenta, chạy ngẫu nhiên trên màn hình khi chạm các cạnh sẽ bật trở lại theo mẫu ở hình sau:
5. Sử dụng Java Awt, Java Applet, Thread vẽ ra màn hình dòng chữ “Java Applet” màu xanh, chạy từ trái sang phải theo mẫu ở hình sau:
6. Sử dụng Java Awt, Java Applet, Thread vẽ ra màn hình dòng chữ “Khoa Công Nghệ Thông Tin” chạy từ phải sang trái mẫu ở hình sau:
7. Sử dụng Java Awt, Java Applet và Thread viết chương trình tạo hình quả bóng chuyển động ngẫu nhiên trên màn hình, khi chạm vào các cạnh sẽ bật trở lại theo mẫu ở hình sau:
8. Viết một chương trình cho thấy rằng những Thread có độ ưu tiên cao được thực thi, những thread có độ ưu tiên thấp sẽ bị dừng.
9. Viết một chương trình ví dụ cho một thread có độ ưu tiên cao sử dụng Sleep để cho những thread có độ ưu tiên thập sẽ chuyển sang chế độ run.
10. Viết một chương trình mà hiển thị một sự đếm lùi từng giây cho đến không, như hình sau:
11. Viết một chương trình hiển thị như hình dưới đây:
Tạo 3 luồng và một luồng chính trong “main”. Thực thi mỗi luồng như một chương trình. Khi chương trình kết thúc, các câu lệnh thoát cho mỗi luồng sẽ được hiển thị. Sử dụng kỹ thuật xử lý ngoại lệ.