CFSDN nhấn mạnh vào việc tạo ra giá trị thông qua mã nguồn mở. Chúng tôi cam kết xây dựng một nền tảng chia sẻ tài nguyên để mọi người làm CNTT có thể tìm thấy thế giới tuyệt vời của riêng mình tại đây.
Bài đăng trên blog CFSDN này về cách JVM liên quan đến "rác" đã được tác giả thu thập và sắp xếp. Nếu bạn quan tâm đến bài viết này, hãy nhớ thích nó.

Trước khi bắt đầu, chúng ta hãy cùng xem lại heap là gì. Như bạn có thể biết, hầu hết các đối tượng Java mà chúng ta tạo ra hàng ngày đều được lưu trữ trên heap, vì vậy không ngoa khi nói rằng heap là một nhóm đối tượng khổng lồ, trong đó các trình quản lý quản lý các thể hiện đối tượng khổng lồ.
Hệ thống phân cấp tham chiếu của các đối tượng trong nhóm đối tượng đôi khi có thể rất sâu. Ví dụ, đối với một giao diện được gọi rất thường xuyên, tốc độ tạo ra các đối tượng là rất ấn tượng. Mối quan hệ giữa các đối tượng có thể được mô tả như một mạng lưới. Mặc dù Java luôn mang lại cho mọi người cảm giác rằng có bộ nhớ vô tận, nhưng các đối tượng không thể tiếp tục tăng mà không giảm, do đó phải có hoạt động thu gom rác.
Vậy JVM tìm rác bằng cách nào?
.
"Thu gom rác" được gọi là GC trong bài viết này.
Bạn còn nhớ bộ phim truyền hình "Diệt Cửu Gia" không?
Ví dụ như Tiêu Hàn Tề tát hoàng đế một cái, mắt thâm quầng, mặt sưng vù. Hoàng đế vô cùng tức giận, muốn hạ lệnh xử tử chín đời nhà họ Tiêu Hàn Tề để xoa dịu mối hận.
Hahahaha ợ ~ Tiểu Hàn đã phê bình xong rồi ~.
Vậy chúng ta hãy xem xét cách diệt trừ chín gia tộc được thực hiện vào thời cổ đại như thế nào? Đầu tiên, chúng ta cần truy ngược về tổ tiên chung (anh cả của gia tộc Tiểu Hàn Bì), sau đó đếm những người có liên quan đến Tiểu Hàn Bì từng người một (Tiểu Hàn Bì thực sự là một trò lừa đảo).
Trên thực tế, việc thu gom rác diễn ra trên heap dựa trên cùng một ý tưởng như "Nine Clans Punishment". Vậy chúng ta hãy cùng phân tích chi tiết cách JVM thực hiện GC?
GC của JVM không được chương trình kiểm soát và nó sẽ tự động được kích hoạt khi đáp ứng được một số điều kiện nhất định.
Khi GC xảy ra, đối với một đối tượng, JVM luôn có thể tìm thấy tổ tiên tham chiếu đến nó. Khi tìm thấy tổ tiên cuối cùng, JVM thấy rằng một số tổ tiên của đối tượng này đã chơi xong, vì vậy chúng sẽ bị JVM giết.
Tại sao vẫn còn những tổ tiên chưa bị giết? Bởi vì những tổ tiên thoát khỏi GC này là GC Roots, và họ trông khá đặc biệt (ngoại hình của họ được mô tả bên dưới).
Khi theo dõi và tìm kiếm từ GC Roots, một chuỗi tham chiếu sẽ được tạo ra. Nếu một đối tượng không có bất kỳ GC Roots nào được liên kết với nó, đối tượng đó sẽ bị tiêu diệt một cách tàn nhẫn. (Châu chấu trên một sợi dây).
Hãy vẽ một bức tranh để xem điều gì đang xảy ra. Như thể hiện trong hình sau, Object5, Object6 và Object7 không thể liên kết với GC Root, vì vậy chúng sẽ bị hủy khi GC xảy ra.

Trên thực tế, cái gọi là thu gom rác xoay quanh GC Roots, nhưng đồng thời, GC Roots cũng có nhiều nguồn rò rỉ bộ nhớ, vì các anh em tham chiếu khác hoàn toàn không có quyền này.
Bạn có thể thắc mắc, GC Roots là loại đối tượng nào?
Bất kể đó là vật gì, điều quan trọng là nó ở đâu (hãy nhìn kỹ hơn~).
GC Roots là gì?
.
Đầu tiên, GC Roots phải là một tập hợp các tham chiếu phải hoạt động. Nói một cách đơn giản, đó là các đối tượng tiềm năng mà chương trình có thể truy cập thông qua các tham chiếu trực tiếp hoặc gián tiếp (điều này vẫn có vẻ hơi khó hiểu).
GC Roots trông như thế này:
- Trong một luồng Java, tham số kiểu tham chiếu, biến cục bộ, giá trị tạm thời, v.v. của tất cả các phương thức hiện đang được gọi. Nghĩa là nhiều tài liệu tham khảo khác nhau liên quan đến khung ngăn xếp của chúng ta.
- Tất cả các lớp Java hiện đang được tải.
- Kiểu tham chiếu biến tĩnh của lớp Java.
- Hằng số kiểu tham chiếu trong nhóm hằng số thời gian chạy.
- Một số tham chiếu đến cấu trúc dữ liệu nội bộ của JVM, chẳng hạn như lớp sun.jvm.hotspot.memory.Univers.
- Giám sát đối tượng để đồng bộ hóa. Ví dụ, phương thức wait() của đối tượng được gọi.
- Xử lý JNI, bao gồm xử lý toàn cục và xử lý cục bộ.
Các GC Roots ở trên có thể được chia thành ba loại sau.
- Nhiều tài liệu tham khảo liên quan đến luồng hoạt động.
- Tham chiếu đến biến tĩnh của lớp.
- Tài liệu tham khảo JNI.
Cuối cùng, chúng ta cần lưu ý rằng chúng ta đang nói về các tham chiếu hoạt động ở đây, không phải các đối tượng. Các đối tượng không thể được sử dụng làm GC Roots.
Toàn bộ quá trình GC là tìm ra những vật thể sống đó và nhận ra không gian còn lại là "vô dụng". Thay vào đó, nó tìm thấy tất cả các vật thể chết và lấy lại không gian mà chúng chiếm giữ. Tóm lại, ngay cả khi heap JVM rất lớn, phương pháp GC dựa trên theo dõi vẫn có thể tái chế dữ liệu một cách nhanh chóng.
Tóm tắt
.
GC Roots là phương pháp phân tích khả năng tiếp cận. Ngoài ra còn có một phương pháp gọi là đếm tham chiếu. Chúng tôi xin giới thiệu sơ lược về nó bên dưới.
Phương pháp đếm tham chiếu: Trong Java, nếu bạn muốn vận hành một đối tượng, trước tiên bạn phải có được tham chiếu đến đối tượng đó. Do đó, bạn có thể sử dụng phương pháp đếm tham chiếu để xác định xem một đối tượng có thể được tái chế hay không. Khi một tham chiếu được thêm vào một đối tượng, bộ đếm tham chiếu sẽ tăng lên 1; khi một tham chiếu bị xóa khỏi một đối tượng, bộ đếm tham chiếu sẽ giảm đi 1; nếu số lượng tham chiếu của một đối tượng là 0, điều đó có nghĩa là đối tượng đó chưa được tham chiếu và có thể được tái chế.
Ưu điểm là việc thu gom rác diễn ra kịp thời và theo thời gian thực hơn. Chỉ cần bộ đếm đối tượng là 0, thao tác tái chế có thể được thực hiện trực tiếp; nhược điểm là không thể giải quyết được vấn đề tham chiếu vòng tròn.
Do lỗi nghiêm trọng của tham chiếu vòng, không có JVM chính thống nào sử dụng đếm tham chiếu để triển khai GC, vì vậy bây giờ bạn có thể quên hoàn toàn việc đếm tham chiếu.
Liên kết gốc: https://mp.weixin.qq.com/s/t4q4lO79FSQMK0WllOcujg.
Cuối cùng, bài viết này về cách JVM liên quan đến "rác" kết thúc tại đây. Nếu bạn muốn biết thêm về cách JVM liên quan đến "rác", vui lòng tìm kiếm các bài viết trên CFSDN hoặc tiếp tục duyệt các bài viết liên quan. Tôi hy vọng bạn sẽ ủng hộ blog của tôi trong tương lai! .
Tôi là một lập trình viên xuất sắc, rất giỏi!