JavaRush /Blog Java /Random-VI /Nghỉ giải lao #210. Tất cả các loại trình thu gom rác tro...

Nghỉ giải lao #210. Tất cả các loại trình thu gom rác trong Java bạn nên biết

Xuất bản trong nhóm
Nguồn: Hackernoon Qua bài đăng này, bạn sẽ tìm hiểu được điểm mạnh và điểm yếu của từng loại trình thu gom rác được sử dụng trong quá trình phát triển Java. Nghỉ giải lao #210.  Tất cả các loại trình thu gom rác trong Java bạn nên biết - 1Câu hỏi về Người thu gom rác (GC) có thể được nghe thấy trong hầu hết các cuộc phỏng vấn. Vì vậy, tôi quyết định thu thập tất cả thông tin cần thiết về họ bằng nguyên tắc yêu thích của tôi - ngắn gọn và đơn giản. Trước tiên, hãy bắt đầu với mục đích của CG và lý do tại sao chúng ta cần nhiều loại trình thu gom rác. Trong các ngôn ngữ như C, chúng ta cần lưu trữ thông tin đối tượng vào bộ nhớ và viết nhiều mã soạn sẵn để giải phóng bộ nhớ đó. Tất nhiên, rò rỉ bộ nhớ là điều phổ biến trong các chương trình như vậy. Java giải quyết vấn đề rò rỉ bộ nhớ bằng cách sử dụng trình thu gom rác. Và bạn, với tư cách là một nhà phát triển, nên biết nên sử dụng công cụ thu gom rác nào tốt nhất. Rất nhiều điều phụ thuộc vào vị trí và cách chương trình của bạn chạy. Nó có thể chạy trên phần cứng yếu hoặc với số lượng lớn đối tượng hoặc chương trình của bạn phải rất nhanh. Dựa trên những điều kiện này, bạn nên điều chỉnh trình thu gom rác của mình để đạt được hiệu suất mong muốn. Vì vậy, hãy bắt đầu.

Cách JVM xử lý bộ nhớ

Máy ảo Java (JVM) chia bộ nhớ thành hai vùng: vùng heap lưu trữ dữ liệu ứng dụng và vùng không heap lưu trữ mã chương trình và dữ liệu khác. Hãy chuyển sự chú ý của chúng ta sang khu vực heap. Đây là nơi chương trình của chúng tôi tạo ra các đối tượng mới. Tất cả các trình thu gom rác đều dựa trên thực tế là nhiều chương trình sử dụng các đối tượng phù du. Tức là những đồ vật này đã được tạo ra, sau đó đã hoàn thành chức năng của chúng và không còn cần thiết nữa. Phần lớn các đối tượng như vậy. Nhưng một số đối tượng tồn tại lâu hơn, thậm chí có thể trong toàn bộ thời gian của chương trình. Đây là nơi nảy sinh ý tưởng chia đồ vật thành thế hệ già và trẻ. Và chúng ta cần kiểm tra thế hệ trẻ thường xuyên. Thực tế là quá trình thu gom rác được chia thành việc dọn dẹp nhỏ, chỉ ảnh hưởng đến thế hệ trẻ và dọn dẹp hoàn toàn, có thể ảnh hưởng đến cả hai thế hệ. Hãy nhớ rằng trình thu gom rác là một chương trình. Và nó đòi hỏi thời gian và nguồn lực từ máy tính của bạn để hoạt động. Điều này cũng ảnh hưởng đến ứng dụng của chúng tôi. Nó ảnh hưởng như thế nào? Ví dụ: để thực hiện thu gom rác, JVM tạm dừng ứng dụng của chúng tôi. Đây được gọi là tạm dừng Stop-The-World (STW). Trong thời gian này, tất cả các luồng ứng dụng đều bị treo. Nhưng ứng dụng bên trong hoàn toàn không biết đến điều này. Đối với ứng dụng, thời gian trôi qua đều đặn. Tại sao điều này lại tệ đến thế? Hãy tưởng tượng, bạn đang viết một loại ứng dụng trao đổi nào đó hoặc một ứng dụng cho hệ thống lái tự động của máy bay. Ứng dụng của bạn có thể chuyển sang chế độ ngủ trong một giây và bản chất vấn đề của bạn có thể thay đổi đáng kể. Nghĩa là, tạm dừng là một tham số quan trọng đối với mọi trình thu gom rác. Thuộc tính cơ bản tiếp theo của trình thu gom rác là tổng thời gian dành cho việc thu gom rác so với tổng thời gian thực hiện của chương trình. Điều này có nghĩa là gì và tại sao nó lại quan trọng như vậy? Thay vì một giai đoạn lớn “Dừng lại thế giới”, chúng ta có thể chọn một thuật toán có nhiều khoảng dừng nhỏ. Tốt nhất là nên nghỉ giải lao một chút, nhưng không có gì miễn phí cả. Trong trường hợp này, chúng tôi trả tiền bằng cách tăng tổng thời gian thực hiện chương trình. Và chúng ta cũng phải tính đến điều này. Tham số tiếp theo là lượng tài nguyên phần cứng. Mỗi bộ sưu tập cần bộ nhớ để lưu trữ thông tin đối tượng và bộ xử lý để thực hiện dọn dẹp. Thông số cuối cùng là tốc độ. Hiệu quả thu gom rác đề cập đến mức độ nhanh chóng và hiệu quả của trình thu gom rác (GC) thu hồi bộ nhớ không còn được chương trình sử dụng. Tất cả các tham số này đều ảnh hưởng đến thuật toán, thuật toán có thể giải phóng bộ nhớ nhanh nhất có thể trong khi tiêu tốn ít tài nguyên nhất. Chúng ta hãy xem các công cụ thu gom rác có sẵn cho chúng ta. Đối với cuộc phỏng vấn bạn cần biết năm điều đầu tiên. Hai cái còn lại khó khăn hơn nhiều.

GC nối tiếp

Serial GC là trình thu thập rác của Máy ảo Java và đã được sử dụng từ thời kỳ đầu của Java. Nó rất hữu ích cho các chương trình có dung lượng nhỏ và chạy trên các máy kém mạnh mẽ hơn. Trình thu gom rác này chia vùng đống thành các vùng, bao gồm Eden và Survivor. Vùng Eden là vùng mà từ đó bộ nhớ ban đầu được phân bổ cho hầu hết các đối tượng. Survivor là một bể chứa các đồ vật sống sót sau quá trình thu gom rác thải ở vùng Eden. Khi đống đầy, các đồ vật sẽ được di chuyển giữa vùng Eden và Survivor. JVM liên tục giám sát chuyển động của các đối tượng vào vùng Survivor và chọn ngưỡng thích hợp cho số lượng chuyển động đó, sau đó các đối tượng được chuyển đến vùng Tenured. Khi không có đủ không gian trong khu vực Tenured, toàn bộ hoạt động thu gom rác sẽ được thực hiện trên các đối tượng của cả hai thế hệ. Ưu điểm chính của trình thu gom rác này là yêu cầu tài nguyên thấp, do đó bộ xử lý có công suất thấp là đủ để thực hiện việc thu thập. Nhược điểm chính của Serial GC là thời gian tạm dừng lâu trong quá trình thu thập rác, đặc biệt là khi xử lý lượng lớn dữ liệu.

CG song song

Trình thu gom rác song song (Parallel CG) tương tự như trình tạo tuần tự. Nó bao gồm xử lý song song một số tác vụ và khả năng tự động điều chỉnh cài đặt hiệu suất. Parallel GC là trình thu thập rác của Máy ảo Java dựa trên ý tưởng của Serial GC, nhưng có thêm tính năng song song và thông minh. Nếu máy tính có nhiều lõi bộ xử lý, phiên bản cũ hơn của JVM sẽ tự động chọn Parallel GC. Vùng heap ở đây được chia thành các vùng giống như trong Serial GC - Eden, Survivor 0, Survivor 1 và Old Gen (Tenured). Tuy nhiên, nhiều luồng tham gia thu gom rác song song và trình thu thập có thể điều chỉnh các thông số hiệu suất được yêu cầu. Mỗi luồng thu thập có một vùng bộ nhớ cần được xóa. Parallel GC cũng có các cài đặt nhằm đạt được hiệu quả thu gom rác cần thiết. Trình thu thập sử dụng số liệu thống kê từ các bộ sưu tập rác trước đó để điều chỉnh cài đặt hiệu suất cho các bộ sưu tập trong tương lai. Parallel GC cung cấp khả năng tự động điều chỉnh các tham số hiệu suất và thời gian tạm dừng xây dựng thấp hơn, nhưng có một nhược điểm nhỏ ở dạng phân mảnh bộ nhớ. Nó phù hợp với hầu hết các ứng dụng, nhưng đối với các chương trình phức tạp hơn thì tốt hơn nên chọn các triển khai thu gom rác nâng cao hơn. Ưu điểm: Nhanh hơn Serial GC trong nhiều trường hợp. Có tốc độ tốt. Nhược điểm: Tiêu tốn nhiều tài nguyên hơn và thời gian tạm dừng có thể khá lâu nhưng chúng ta có thể điều chỉnh thời lượng tạm dừng tối đa của Stop-The-World.

Quét đánh dấu đồng thời

Trình thu thập rác quét đánh dấu đồng thời (CMS) nhằm mục đích giảm thời lượng tạm dừng tối đa bằng cách chạy một số tác vụ thu gom rác đồng thời với các luồng ứng dụng. Trình thu gom rác này phù hợp để quản lý lượng lớn dữ liệu trong bộ nhớ. Quét đánh dấu đồng thời (CMS) là một giải pháp thay thế cho Parallel GC trong Máy ảo Java (JVM). Nó dành cho các ứng dụng yêu cầu quyền truy cập vào nhiều lõi bộ xử lý và nhạy cảm với các trạng thái tạm dừng Stop-The-World. CMS thực hiện các bước thu gom rác song song với chương trình chính, cho phép chương trình chạy không ngừng. Nó sử dụng cách tổ chức bộ nhớ giống như các bộ sưu tập Nối tiếp và Song song, nhưng không đợi khu vực Tenured được lấp đầy trước khi chạy quá trình thanh lọc thế hệ cũ. Thay vào đó, nó chạy ở chế độ nền và cố gắng giữ cho vùng được thuê nhỏ gọn. Quét đánh dấu đồng thời bắt đầu bằng giai đoạn đánh dấu ban đầu, dừng nhanh các luồng chính của ứng dụng và đánh dấu tất cả các đối tượng có thể truy cập được từ root. Sau đó, các luồng chính của ứng dụng sẽ tiếp tục và CMS bắt đầu tìm kiếm tất cả các đối tượng đang hoạt động có thể truy cập được bằng các liên kết từ các đối tượng gốc được đánh dấu. Sau khi đánh dấu tất cả các vật thể sống, bộ sưu tập sẽ xóa bộ nhớ của các vật thể chết theo một số luồng song song. Một trong những lợi ích của CMS là tập trung vào việc giảm thiểu thời gian ngừng hoạt động, điều này rất quan trọng đối với nhiều ứng dụng. Tuy nhiên, nó đòi hỏi phải hy sinh về tài nguyên CPU và băng thông tổng thể. Ngoài ra, CMS không nén các đối tượng ở thế hệ cũ dẫn đến tình trạng phân mảnh. Việc tạm dừng lâu do lỗi chế độ song song có thể xảy ra có thể là một bất ngờ khó chịu (mặc dù chúng không xảy ra thường xuyên). Nếu có đủ bộ nhớ, CMS có thể tránh được tình trạng tạm dừng như vậy. Ưu điểm: Nhanh chóng. Có những khoảng dừng nhỏ ở Stop-The-World. Nhược điểm: tiêu tốn nhiều bộ nhớ hơn, nếu không đủ bộ nhớ, một số lần tạm dừng có thể kéo dài. Không tốt lắm nếu ứng dụng tạo ra nhiều đối tượng.

Rác-Đầu Tiên

Garbage-First (G1) được coi là giải pháp thay thế cho CMS, đặc biệt dành cho các ứng dụng máy chủ chạy trên máy chủ đa bộ xử lý và quản lý các tập dữ liệu lớn. Trình thu gom rác G1 chuyển đổi bộ nhớ thành nhiều vùng có kích thước bằng nhau, ngoại trừ các vùng lớn (được tạo bằng cách hợp nhất các vùng thông thường để chứa các đối tượng lớn). Các khu vực không cần phải được tổ chức thành một hàng và có thể thay đổi liên kết thế hệ của chúng. Các cuộc thanh lọc nhỏ được thực hiện định kỳ đối với thế hệ trẻ và di chuyển các đối tượng đến khu vực Người sống sót hoặc nâng cấp chúng lên thế hệ cũ và chuyển chúng sang Tenured. Việc làm sạch chỉ được thực hiện ở những khu vực cần tránh vượt quá thời gian mong muốn. Người thu gom tự mình dự đoán và lựa chọn những khu vực có lượng rác lớn nhất để dọn dẹp. Quét toàn bộ sử dụng vòng đánh dấu để tạo danh sách các đối tượng trực tiếp chạy song song với ứng dụng chính. Sau chu kỳ đánh dấu, G1 chuyển sang chạy các cuộc thanh lọc hỗn hợp, bổ sung các vùng thế hệ cũ hơn vào tập hợp các vùng thế hệ trẻ sẽ được thanh lọc. Trình thu thập rác G1 được coi là chính xác hơn trình thu thập CMS trong việc dự đoán kích thước tạm dừng và phân phối việc thu thập rác tốt hơn theo thời gian để ngăn chặn thời gian ngừng hoạt động của ứng dụng kéo dài, đặc biệt là với kích thước vùng heap lớn. Nó cũng không phân mảnh bộ nhớ như bộ sưu tập CMS. Tuy nhiên, bộ thu thập G1 yêu cầu nhiều tài nguyên CPU hơn để chạy song song với chương trình chính, điều này làm giảm thông lượng ứng dụng. Ưu điểm: Hoạt động tốt hơn CMS. Có thời gian tạm dừng ngắn hơn. Nhược điểm: Tiêu tốn nhiều tài nguyên CPU. Ngoài ra, nó sẽ tiêu tốn nhiều bộ nhớ hơn nếu chúng ta có nhiều đối tượng khá lớn (hơn 500 KB) vì nó đặt các đối tượng đó vào một vùng (1-32 MB).

Epsilon GC

Epsilon GC được thiết kế cho các tình huống không cần thu gom rác. Nó không thực hiện thu thập rác mà sử dụng TLAB (bộ đệm phân bổ luồng cục bộ) để phân bổ các đối tượng mới - bộ nhớ đệm nhỏ được yêu cầu bởi các luồng riêng lẻ từ vùng heap. Các đối tượng lớn không vừa với khối bộ nhớ yêu cầu bộ đệm dành riêng cho chúng. Khi Epsilon GC hết tài nguyên, OutOfMemoryError sẽ được tạo và quá trình kết thúc. Lợi ích của Epsilon GC bao gồm yêu cầu tài nguyên thấp hơn và phân bổ bộ nhớ nhanh hơn cho các ứng dụng tạo ra tất cả đối tượng chúng cần khi khởi động hoặc chạy các ứng dụng có thời gian sử dụng ngắn không sử dụng hết bộ nhớ được phân bổ. Epsilon GC cũng có thể giúp phân tích các yêu cầu tài nguyên mà các trình thu gom rác khác thêm vào ứng dụng của bạn. Ưu điểm: Rất nhanh. Nhược điểm: Không xóa đồ vật :) Hai bộ sưu tập tiếp theo là loại tiên tiến nhất nhưng cũng phức tạp nhất. Vì vậy, chúng tôi sẽ xem xét chúng một cách ngắn gọn.

ZGC

ZGC có thể duy trì độ trễ dưới một phần nghìn giây ngay cả khi xử lý lượng dữ liệu khổng lồ. ZGC là trình thu thập rác do Oracle phát triển cho Java, được thiết kế để cung cấp thông lượng cao và độ trễ thấp khi xử lý các đống lớn (lên đến 16 TB). ZGC dựa trên nguyên tắc bộ nhớ ảo và sử dụng các dấu màu khác nhau để theo dõi trạng thái của đối tượng trong quá trình thu gom rác. Ưu điểm: Thời gian tạm dừng chưa đến một phần nghìn giây, ngay cả trên các vùng dữ liệu lớn, rất hữu ích cho các ứng dụng yêu cầu thời gian xử lý truy vấn ngắn. Nó hoạt động với đống rất lớn với thông lượng tốt. ZGC có thể nén bộ nhớ heap trong quá trình thu gom rác. Nhược điểm: Sử dụng CPU cao và yêu cầu hiệu suất đáng kể, có thể làm chậm thời gian khởi chạy ứng dụng.

Shenandoah G.C.

Shenandoah GC là một công cụ thu gom rác khác có thời gian tạm dừng ngắn bất kể kích thước heap. Trình thu gom rác này được phát triển bởi Red Hat. Nó được thiết kế để giảm thiểu thời gian ứng dụng dành cho việc thu gom rác. Giống như ZGC, nó là một bộ thu song song, có nghĩa là nó chạy trong khi ứng dụng đang chạy, giảm thiểu tình trạng tạm dừng. Shenandoah GC sử dụng “con trỏ chuyển tiếp” để di chuyển các đối tượng trong quá trình thu gom rác. Nó cũng có một kỹ thuật gọi là “loại bỏ rào cản tải” để cải thiện hiệu suất. Ưu điểm: Shenandoah GC có thể đạt được thời gian tạm dừng ngắn, thường dưới 10 mili giây, ngay cả đối với các đống dữ liệu lớn. Thông lượng tốt. Nhược điểm: tải bộ xử lý cao và khó làm việc dưới tải nặng.

Phần kết luận

Thu gom rác là một trong những nhiệm vụ khó khăn nhất trong lập trình. Những phát triển mới liên tục được thực hiện theo hướng này. Mặc dù hiếm khi các lập trình viên điều chỉnh GC nhưng bạn vẫn cần có ít nhất kiến ​​thức sơ bộ về cách hoạt động của công cụ thu gom rác.
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION