CodeGym /Blog Java /Ngẫu nhiên /Tìm hiểu thêm về bộ thu gom rác

Tìm hiểu thêm về bộ thu gom rác

Xuất bản trong nhóm
CHÀO! Trong bài học trước, lần đầu tiên chúng ta làm quen với trình thu gom rác tích hợp sẵn của Java và có ý tưởng sơ bộ về cách thức hoạt động của nó. Nó hoạt động ở chế độ nền trong khi chương trình của bạn đang chạy, thu thập các đối tượng không cần thiết sẽ bị xóa sau đó. Do đó, nó giải phóng bộ nhớ có thể được sử dụng để tạo các đối tượng mới trong tương lai.
Tìm hiểu thêm về bộ thu gom rác - 1
Trong bài học này, chúng ta sẽ thảo luận chi tiết hơn về cách thức hoạt động của nó. Ví dụ, làm thế nào và khi nào một đối tượng trở nên không cần thiết? Và làm thế nào để người thu gom rác tìm ra? Đây là những câu hỏi mà chúng ta sẽ trả lời trong bài học hôm nay :) Bài học sẽ giống như phần tổng quan hơn: bạn không cần phải học thuộc lòng tài liệu này. Mục đích chủ yếu là để mở rộng tầm nhìn của bạn về cách thức hoạt động của bộ nhớ và bộ thu gom rác, vì vậy hãy đọc qua và tìm một cái gì đó mới cho chính mình :) Đi thôi! Điều đầu tiên bạn cần nhớ là trình thu gom rác hoạt động song song với chương trình của bạn. Nó không phải là một phần của chương trình của bạn. Nó chạy riêng (trong bài học trước, chúng tôi đã so sánh nó với máy hút bụi rô-bốt) Nhưng không phải lúc nào cũng vậy. Bộ sưu tập rác từng được thực hiện trên cùng một chuỗi với chương trình của bạn. Theo một số lịch trình (cứ sau vài phút), bộ thu gom rác sẽ kiểm tra sự hiện diện của các đối tượng không mong muốn trong chương trình. Vấn đề là chương trình sẽ bị treo (không thực thi) trong quá trình kiểm tra và thu gom rác này. Hãy tưởng tượng bạn đang ngồi trong văn phòng làm việc. Nhưng sau đó, người phụ nữ dọn dẹp đến để rửa sàn nhà. Cô ấy đuổi bạn ra khỏi máy tính trong 5 phút và bạn đợi cho đến khi cô ấy dọn dẹp xong. Trong thời gian này, bạn không thể làm việc. Đó là về cách hoạt động của bộ sưu tập rác :) Cơ chế này sau đó đã được thay đổi và hiện tại bộ thu gom rác chạy trong nền, không cản trở công việc của chính chương trình. Bạn đã biết rằng một đối tượng chết khi nó không còn tham chiếu nữa. Thực tế,bộ thu gom rác không tính các tham chiếu đối tượng . Đầu tiên, điều này có thể mất một thời gian dài. Thứ hai, nó không hiệu quả lắm. Rốt cuộc, các đối tượng có thể tham khảo lẫn nhau! Tìm hiểu thêm về bộ thu gom rác - 2Hình này cho thấy một ví dụ trong đó 3 đối tượng tham chiếu đến nhau, nhưng không có đối tượng nào khác tham chiếu đến chúng. Nói cách khác, phần còn lại của chương trình không cần đến chúng. Nếu bộ thu gom rác chỉ tính các tham chiếu, thì 3 đối tượng này sẽ không được thu thập và bộ nhớ sẽ không được giải phóng (có các tham chiếu đến chúng!). Chúng ta có thể so sánh điều này với một con tàu vũ trụ. Trong chuyến bay, các phi hành gia quyết định kiểm tra danh sách các phụ tùng thay thế có sẵn để sửa chữa. Trong số những thứ khác, họ tìm thấy vô lăng và bàn đạp của một chiếc ô tô bình thường. Rõ ràng, chúng không cần thiết ở đây và đang chiếm dung lượng một cách không cần thiết (mặc dù hai phần này có liên quan với nhau và có một số chức năng). Nhưng bên trong phi thuyền, chúng là thứ rác rưởi vô dụng nên vứt bỏ. Theo đó, trong Java, quyết định được đưa ra để thu gom rác không dựa trên việc đếm tham chiếu,có thể truy cậpkhông thể truy cập . Làm cách nào để xác định xem một đối tượng có thể truy cập được không? Tất cả chỉ đơn giản là khéo léo. Một đối tượng có thể truy cập được nếu nó được tham chiếu bởi một đối tượng có thể truy cập khác. Do đó, chúng tôi nhận được một "chuỗi khả năng tiếp cận". Nó bắt đầu khi chương trình bắt đầu và tiếp tục trong suốt thời gian của chương trình. Nó trông giống như thế này: Tìm hiểu thêm về bộ thu gom rác - 3 Mũi tên trong hình biểu thị mã thực thi của chương trình của chúng ta. Mã (ví dụ: main()phương thức) tạo tham chiếu đến các đối tượng. Các đối tượng này có thể tham chiếu đến các đối tượng khác, các đối tượng này đến các đối tượng khác, v.v. Điều này tạo thành một chuỗi tham chiếu. Nếu bạn có thể theo dõi chuỗi từ một đối tượng đến "tham chiếu gốc" (tham chiếu gốc được tạo trực tiếp trong mã thực thi), thì nó được coi là có thể truy cập được. Những đối tượng như vậy được đánh dấu màu đen trong hình. Nhưng một đối tượng không thể truy cập được nếu đối tượng đó rơi ra khỏi chuỗi này, tức là không có biến nào trong mã hiện đang được thực thi tham chiếu đến nó và không thể truy cập nó thông qua "chuỗi tham chiếu". Trong chương trình của chúng tôi, hai đối tượng như vậy được đánh dấu màu đỏ. Lưu ý rằng các đối tượng "đỏ" này có tham chiếu đến nhau. Nhưng như chúng tôi đã nói trước đó, trình thu gom rác hiện đại của Java không tính các tham chiếu. Nó xác định xem một đối tượng có thể truy cập được hay không thể truy cập được. Kết quả là, nó sẽ bám vào hai đối tượng màu đỏ trong hình. Bây giờ chúng ta hãy xem xét toàn bộ quá trình từ đầu đến cuối. Khi làm như vậy, chúng ta cũng sẽ xem cách sắp xếp bộ nhớ trong Java :) Tất cả các đối tượng Java được lưu trữ trong một vùng bộ nhớ đặc biệt gọi là heap . Trong ngôn ngữ hàng ngày, heap thường là một núi vật phẩm, nơi mọi thứ được trộn lẫn với nhau. Nhưng đó không phải là đống trong Java. Cấu trúc của nó rất logic và hợp lý. Tại một số thời điểm, các lập trình viên Java nhận thấy rằng tất cả các đối tượng của họ có thể được chia thành hai loại: đối tượng đơn giản"đối tượng tồn tại lâu dài". “Vật sống lâu” là vật tồn tại qua nhiều vòng thu gom rác. Họ thường sống cho đến khi chương trình kết thúc. Cuối cùng, toàn bộ đống, nơi lưu trữ tất cả các đối tượng, được chia thành nhiều phần. Phần đầu tiên có một cái tên đẹp: eden(từ "Vườn Địa đàng" trong Kinh thánh). Tên này phù hợp, bởi vì đây là nơi các đối tượng kết thúc sau khi chúng được tạo. Đây là một phần của bộ nhớ nơi các đối tượng mới được tạo khi chúng ta sử dụng từ khóa new. Rất nhiều đối tượng có thể được tạo ra. Khi khu vực này hết dung lượng, quá trình thu gom rác "nhanh" ban đầu sẽ bắt đầu. Chúng tôi phải nói rằng người thu gom rác rất thông minh. Nó chọn một thuật toán dựa trên việc đống có nhiều rác hơn hay nhiều đối tượng trực tiếp hơn. Nếu hầu hết tất cả các đối tượng đều là rác, bộ sưu tập sẽ đánh dấu các đối tượng đang hoạt động và di chuyển chúng đến một vùng khác của bộ nhớ. Sau đó, khu vực hiện tại được xóa hoàn toàn. Nếu không có nhiều rác và đống này chủ yếu là các vật thể sống, người thu gom sẽ đánh dấu rác, dọn sạch và đóng gói các vật thể khác lại với nhau. Chúng tôi đã nói "một không gian sinh tồn . Đến lượt mình, một không gian sinh tồn được chia thành các thế hệ . Mỗi đối tượng thuộc về một thế hệ cụ thể, tùy thuộc vào số vòng thu gom rác mà nó đã tồn tại. Nếu một đối tượng đã tồn tại sau một vòng thu gom rác, thì đối tượng đó thuộc "Thế hệ 1"; nếu là 5 thì là "Thế hệ 5". Cùng nhau, Eden và một không gian sinh tồn tạo thành một khu vực được gọi là thế hệ trẻ . Ngoài thế hệ trẻ, đống còn có một vùng ký ức khác gọi là thế hệ cũ. Đây chính xác là khu vực mà các vật thể tồn tại lâu dài đã tồn tại qua nhiều vòng thu gom rác kết thúc. Có những lợi thế để giữ chúng tách biệt với tất cả những thứ khác. Bộ sưu tập rác đầy đủ chỉ được thực hiện khi thế hệ cũ đầy, tức là có quá nhiều đối tượng tồn tại lâu trong chương trình nên không có đủ bộ nhớ. Quá trình này liên quan đến nhiều hơn một vùng bộ nhớ. Nói chung, nó liên quan đến tất cả các đối tượng được tạo bởi máy Java. Đương nhiên, điều này tốn nhiều thời gian và nguồn lực hơn. Đây chính xác là quyết định được đưa ra để lưu trữ các đối tượng tồn tại lâu dài một cách riêng biệt. “Thu gom rác nhanh” được thực hiện khi các khu vực khác hết chỗ chứa. Điều này chỉ liên quan đến một lĩnh vực, làm cho nó nhanh hơn và hiệu quả hơn. Cuối cùng, ngay cả khi khu vực dành cho các đối tượng tồn tại lâu dài đã được lấp đầy hoàn toàn, bộ sưu tập rác đầy đủ được kích hoạt. Do đó, người thu gom chỉ sử dụng công cụ "nặng nhất" khi không thể tránh được. Đây là một đại diện trực quan của cấu trúc heap và bộ sưu tập rác: Tìm hiểu thêm về bộ thu gom rác - 4
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION