× Giới thiệu Lịch khai giảng Tin tức Sản phẩm học viên

Garbage Collection trong Java - Tìm hiểu về Bộ thu gom rác trong Java

14/10/2021 13:17

Garbage Collection trong Java là một trong những tính năng quan trọng nhất trong Java khiến nó trở nên phổ biến trong tất cả các ngôn ngữ lập trình. Quá trình Garbage Collection được thực hiện ngầm trong Java. Do đó, nó còn được gọi là Garbage Collection tự động trong Java. Lập trình viên không cần phải viết mã rõ ràng để xóa các đối tượng. Hôm nay trong bài viết này, chúng ta sẽ cùng nhau tìm hiểu khái niệm về Garbage Collection trong Java một cách chi tiết cùng với các phương thức và thuật toán của nó. Hãy bắt đầu thảo luận về khái niệm Garbage Collection trong Java.

Khái niệm về Garbage Collection trong Java

Garbage Collection là kỹ thuật được sử dụng trong Java để phân bổ hoặc loại bỏ các đối tượng không thể truy cập và bộ nhớ không sử dụng. Ngay từ cái tên, chúng ta có thể hiểu rằng Garbage Collection liên quan đến việc theo dõi và xóa rác khỏi vùng nhớ.

Tuy nhiên, trên thực tế, Garbage Collection theo dõi từng đối tượng có sẵn trong không gian heap JVM và loại bỏ những đối tượng không sử dụng.

Garbage Collection trong Java

Chúng ta biết rằng tất cả các đối tượng mà chúng ta tạo động đều được cấp phát trong bộ nhớ heap của ứng dụng. Thông thường, lập trình viên có nhiệm vụ vừa tạo vừa xóa các đối tượng trong chương trình, nhưng lập trình viên thường bỏ qua việc xóa đối tượng. Điều này tạo ra vấn đề OutOfMemoryErrors do không đủ bộ nhớ vì không xóa các đối tượng không mong muốn.

Trong Java, lập trình viên không phải lo lắng về vấn đề giải phóng bộ nhớ của các đối tượng không sử dụng hoặc không mong muốn này, vì hệ thống Garbage Collection luôn chạy ở chế độ nền và mục đích chính của nó là giải phóng bộ nhớ heap bằng cách xóa các đối tượng không thể truy cập.

Về cơ bản, Garbage Collection trong Java là quá trình theo dõi tất cả các đối tượng vẫn còn được sử dụng và đánh dấu phần còn lại của chúng là rác. Quá trình Gom rác trong Java được coi là một lược đồ quản lý bộ nhớ tự động vì người lập trình không phải định vị các đối tượng một cách rõ ràng. Tập hợp rác trong Java chạy trên các luồng có mức độ ưu tiên thấp.

Việc triển khai Garbage Collection có trong JVM (Máy ảo Java). Mỗi JVM có thể thực hiện Garbage Collection. Nhưng chỉ có một yêu cầu; rằng nó phải đáp ứng đặc điểm kỹ thuật JVM. Oracle's HotSpot là một trong những JVM phổ biến nhất cung cấp một tập hợp các tùy chọn Garbage Collection mạnh mẽ và hoàn thiện.

Vòng đời đối tượng trong Java

Vòng đời đối tượng trong Java có thể được chia thành 3 giai đoạn:

1. Tạo đối tượng

Nói chung, để tạo một đối tượng, chúng tôi sử dụng một từ khóa new. Ví dụ:

MyClass obj = new MyClass () ;

Chúng ta đã tạo đối tượng obj của lớp MyClass. Khi chúng ta tạo đối tượng, một lượng bộ nhớ cụ thể sẽ được cấp phát để lưu trữ đối tượng đó. Lượng bộ nhớ được cấp phát cho các đối tượng có thể thay đổi tùy theo kiến ​​trúc và JVM.

2. Đối tượng sử dụng

Trong giai đoạn này, Đối tượng được sử dụng bởi các đối tượng khác của ứng dụng trong Java. Trong quá trình sử dụng, đối tượng nằm trong bộ nhớ và có thể tham chiếu hoặc chứa tham chiếu đến các đối tượng khác.

3. Sự phá hủy đối tượng

Hệ thống Garbage Collection giám sát các đối tượng và giữ số lượng tham chiếu đến từng đối tượng. Không cần các đối tượng như vậy trong chương trình của chúng ta nếu không có tham chiếu đến đối tượng này, vì vậy việc phân bổ bộ nhớ không sử dụng này là điều hoàn hảo.

Đối tượng không thể truy cập trong Java

Khi một đối tượng không chứa bất kỳ tham chiếu “có thể truy cập” nào đối với nó, thì chúng ta gọi nó là đối tượng không thể truy cập. Các đối tượng này cũng có thể được gọi là đối tượng không tham chiếu.

Ví dụ về các đối tượng không thể truy cập: 

Double d = new Double(5.6);

// the new Double object is reachable via the reference in 'd'

d = null;

// the Integer object is no longer reachable. Now d is an unreachable object.

Tính đủ điều kiện để Garbage Collection trong Java

Một đối tượng có thể đủ điều kiện để Garbage Collection trong Java nếu và chỉ khi nó không thể truy cập được. Trong chương trình trên, sau khi khai báo d là null; đối tượng kép 4 trong vùng đống trở nên đủ điều kiện để Garbage Collection.

Tính đủ điều kiện của đối tượng

Mặc dù Java có tính năng Garbage Collection tự động, nhưng một đối tượng phải được thực hiện theo cách thủ công. Có nhiều cách khác nhau để biết liệu đối tượng có đủ điều kiện cho Bộ sưu tập rác trong Java hay không.

Nói chung, có bốn cách trong Java để làm cho một đối tượng đủ điều kiện để Garbage Collection:

  • Vô hiệu hóa biến tham chiếu
  • Gán lại biến tham chiếu
  • Đảo cô lập
  • Tạo các đối tượng bên trong một lớp

Các cách yêu cầu JVM chạy Garbage Collection

Ngay cả khi chúng tôi làm cho một đối tượng đủ điều kiện để Garbage Collection trong Java, nó có thể đủ điều kiện hoặc không đủ điều kiện để Máy ảo Java (JVM) phá hủy. Vì vậy, có một số cách để yêu cầu JVM hủy đối tượng này và thực hiện Garbage Collection.

Có hai cách để yêu cầu JVM để thu thập Rác trong Java là:

  • Sử dụng phương thức System.gc() 
  • Sử dụng phương thức Runtime.getRuntime().gc() 

Thuật toán của Garbage Collection trong Java

Thuật toán của Garbage Collection trong Java giúp loại bỏ các đối tượng không được tham chiếu hoặc không thể truy cập. Các thuật toán này luôn chạy ở chế độ nền. Có một số loại bộ thuật toán Garbage Collection khác nhau trong Java chạy ở chế độ nền. Và trong số đó, một trong những thuật toán là thuật toán Đánh dấu và Quét.

Thuật toán đánh dấu và quét

Thuật toán Đánh dấu và Quét là một thuật toán cơ bản và ban đầu để Garbage Collection trong Java. Thuật toán này về cơ bản thực hiện hai chức năng chính: đánh dấu và quét. Thứ nhất, nó sẽ theo dõi và phát hiện các đối tượng không thể truy cập và thứ hai, nó sẽ giải phóng các đối tượng này khỏi vùng bộ nhớ heap để lập trình viên có thể sử dụng lại.

1. Đánh dấu pha - Đánh dấu các đối tượng sống

Đây là giai đoạn đầu tiên của thuật toán, trong đó có việc phát hiện tất cả các đối tượng vẫn còn sống. Đây là giai đoạn mà bộ Garbage Collection xác định phần nào của bộ nhớ đang được sử dụng và phần nào không được sử dụng.

Trong pha này khi điều kiện được thực hiện, bit kiểm tra của nó được đặt thành 0 hoặc sai. Chúng tôi đặt bit được đánh dấu thành 1 hoặc true cho tất cả các đối tượng có thể truy cập.

Ở đây chúng ta có thể coi mỗi đối tượng là một nút và sau đó chúng ta truy cập tất cả các đối tượng hoặc nút có thể truy cập được từ đối tượng / nút này và nó lặp lại cho đến khi chúng ta đã truy cập tất cả các nút có thể truy cập.

  • Gốc là một biến tham chiếu đến một đối tượng và có thể truy cập trực tiếp bởi một biến cục bộ. Chúng ta sẽ cho rằng chúng ta chỉ có một gốc.
  • Chúng ta có thể sử dụng markBit (obj) để truy cập bit đánh dấu cho một đối tượng.

Thuật toán đánh dấu pha

Mark(root)

If markedBit(root) = false then

    markedBit(root) = true

    For each v referenced by a root

         Mark(v)

>>> Đọc thêm: Constructor Chaining trong Java - Tất tần tật về Constructor Chaining

2. Giai đoạn quét - Loại bỏ các vật chết

Thuật toán pha quét “xóa” tất cả các đối tượng không thể truy cập hoặc không thể truy cập được, nó giải phóng vùng bộ nhớ được lưu trữ cho tất cả các đối tượng không thể truy cập. Mỗi mục có giá trị kiểm tra được đặt thành false sẽ bị xóa khỏi bộ nhớ ngăn xếp, đối với mọi đối tượng có thể truy cập khác, chúng tôi đặt giá trị của bit được đóng dấu thành false.

Hiện tại, bit kiểm tra cho tất cả các đối tượng có thể truy cập được đặt thành false.

Thuật toán thu thập quét:

Sweep()

For each object p in a heap

    If markedBit(p) = true then

       markedBit(p) = false

    else

       heap.release(p)

 

Thuật toán 'Mark and Sweep' còn được gọi là bộ Garbage Collection theo dõi vì thuật toán này được sử dụng để theo dõi các đối tượng. Ví dụ:

  • Các bit được đánh dấu được đặt thành false.
  • Các đối tượng có thể tiếp cận được đặt thành true.
  • Các đối tượng không thể tiếp cận được xóa khỏi đống.

Ưu điểm của thuật toán đánh dấu và quét

  • Đó là một quá trình tuần hoàn.
  • Không có chi phí bổ sung nào xảy ra trong quá trình thực thi một thuật toán.

Nhược điểm của thuật toán đánh dấu và quét

  • Trong khi thuật toán Garbage Collection Java chạy, việc thực thi chương trình bình thường sẽ dừng lại.
  • Nó chạy khác nhau nhiều lần trên một chương trình.

>>> Đọc thêm:  Hướng dẫn JDBC trong Java - Kiến trúc, thành phần và cách làm việc

Ưu điểm và nhược điểm của Garbage Collection trong Java

Ưu điểm của việc Garbage Collection:

  • Không cần phải xử lý việc cấp phát / phân bổ bộ nhớ theo cách thủ công vì JVM tự động thực hiện việc Garbage Collection cho không gian chưa sử dụng trong Java.
  • Không có chi phí xử lý Con trỏ nguy hiểm.
  • Garbage Collection sẽ xử lý tốt phần quản lý Rò rỉ Bộ nhớ Tự động (Automatic Memory Leak management)..

Nhược điểm của việc Garbage Collection:

  • Yêu cầu nhiều hơn về sức mạnh của CPU bên cạnh ứng dụng gốc, vì JVM phải theo dõi quá trình tạo / xóa tham chiếu đối tượng. Điều này có thể ảnh hưởng đến hiệu suất của các yêu cầu đòi hỏi một bộ nhớ lớn.
  • Lập trình viên không có bất kỳ quyền kiểm soát nào đối với việc lập lịch thời gian CPU dành riêng cho việc giải phóng các đối tượng không thể truy cập.
  • Sử dụng một số triển khai Garbage Collection, ứng dụng có thể dừng không thể đoán trước.
  • Quản lý bộ nhớ tự động không hiệu quả nhiều khi phân bổ / phân bổ bộ nhớ thủ công thích hợp.

Kết luận: 

Garbage Collection trong Java rất hữu ích để ngăn chặn rò rỉ bộ nhớ và sử dụng không gian. Trong hướng dẫn Java này, chúng ta đã tìm hiểu về Garbage Collection trong Java và cách hoạt động của nó. Chúng ta đã thảo luận về các điều khoản quan trọng liên quan đến Java Garbage Collection và các thuật toán Garbage Collection. Có bốn loại Trình Garbage Collection Java mà chúng ta đã tìm hiểu trong bài viết này. Chúng tôi đã thảo luận về thuật toán Java Mark và Sweep cùng với những ưu và nhược điểm của nó. Chúng ta cũng đã xem xét những ưu điểm và nhược điểm của Garbage Collection trong Java. 

Hy vọng bạn đã nắm rõ và Garbage Collection và có thể áp dụng nó trong chương trình của mình. Tìm hiểu thêm về Java và các ngôn ngữ lập trình khác qua các khóa học lập trình tại Viện công nghệ thông tin T3H.