Máy ảo Java - Thu gom rác
Vòng đời của một đối tượng Java được quản lý bởi JVM. Khi một đối tượng được lập trình viên tạo ra, chúng ta không cần lo lắng về phần còn lại của vòng đời của nó. JVM sẽ tự động tìm những đối tượng không còn được sử dụng nữa và lấy lại bộ nhớ của chúng từ đống.
Thu gom rác là một hoạt động chính mà JVM thực hiện và việc điều chỉnh nó theo nhu cầu của chúng ta có thể mang lại hiệu suất lớn cho ứng dụng của chúng ta. Có nhiều thuật toán thu gom rác được cung cấp bởi các JVM hiện đại. Chúng ta cần biết về nhu cầu của ứng dụng để quyết định sử dụng thuật toán nào.
Bạn không thể định vị một đối tượng theo lập trình trong Java, giống như bạn có thể làm trong các ngôn ngữ không phải GC như C và C ++. Do đó, bạn không thể có các tham chiếu lơ lửng trong Java. Tuy nhiên, bạn có thể có các tham chiếu rỗng (các tham chiếu tham chiếu đến một vùng bộ nhớ mà JVM sẽ không bao giờ lưu trữ các đối tượng). Bất cứ khi nào một tham chiếu rỗng được sử dụng, JVM sẽ ném một NullPointerException.
Lưu ý rằng mặc dù hiếm khi tìm thấy rò rỉ bộ nhớ trong các chương trình Java nhờ GC, nhưng chúng vẫn xảy ra. Chúng tôi sẽ tạo ra một rò rỉ bộ nhớ ở cuối chương này.
Các GC sau được sử dụng trong các JVM hiện đại
- Bộ sưu tập nối tiếp
- Bộ thu thông lượng
- Bộ sưu tập CMS
- Bộ sưu tập G1
Mỗi thuật toán trên thực hiện cùng một nhiệm vụ - tìm kiếm các đối tượng không còn được sử dụng và lấy lại bộ nhớ mà chúng chiếm trong đống. Một trong những cách tiếp cận đơn giản cho điều này là đếm số lượng tham chiếu mà mỗi đối tượng có và giải phóng nó ngay khi số lượng tham chiếu chuyển sang 0 (đây còn được gọi là đếm tham chiếu). Sao lại ngây thơ thế này? Hãy xem xét một danh sách liên kết vòng tròn. Mỗi nút của nó sẽ có một tham chiếu đến nó, nhưng toàn bộ đối tượng sẽ không được tham chiếu từ bất kỳ đâu, và lý tưởng là nên được giải phóng.
JVM không chỉ giải phóng bộ nhớ mà còn kết hợp các bộ nhớ nhỏ thành bộ nhớ lớn hơn. Điều này được thực hiện để ngăn chặn sự phân mảnh bộ nhớ.
Một lưu ý đơn giản, một thuật toán GC điển hình thực hiện các hoạt động sau:
- Tìm đồ vật không sử dụng
- Giải phóng bộ nhớ mà chúng chiếm trong heap
- Kết dính các mảnh
GC phải dừng các luồng ứng dụng trong khi nó đang chạy. Điều này là do nó di chuyển các đối tượng xung quanh khi nó chạy, và do đó, những đối tượng đó không thể được sử dụng. Những điểm dừng như vậy được gọi là 'tạm dừng trên toàn thế giới và giảm thiểu tần suất và thời lượng của những lần tạm dừng này là mục tiêu của chúng tôi khi điều chỉnh GC của mình.
Coalescing bộ nhớ
Dưới đây là một minh chứng đơn giản về liên kết bộ nhớ
Phần bóng mờ là các đối tượng cần được giải phóng. Ngay cả sau khi tất cả không gian được lấy lại, chúng tôi chỉ có thể cấp phát một đối tượng có kích thước tối đa = 75Kb. Điều này thậm chí sau khi chúng tôi có 200Kb dung lượng trống như hình dưới đây