Go sử dụng loại Rác Thu gom nào?


111

Go là một ngôn ngữ được thu gom rác:

http://golang.org/doc/go_faq.html#garbage_collection

Ở đây nó nói rằng nó là một công cụ thu gom rác đánh dấu và quét, nhưng nó không đi sâu vào chi tiết và một sự thay thế đang được thực hiện ... tuy nhiên, đoạn này có vẻ như chưa được cập nhật nhiều kể từ khi Go được phát hành.

Nó vẫn đánh dấu và quét? Nó là bảo thủ hay chính xác? Nó là thế hệ?


2
Để có một cuộc thảo luận dài về lịch sử của công cụ thu gom rác Go cho đến tháng 7 năm 2018, hãy xem blog.golang.org/ismmkeynote
Wildcard

Câu trả lời:


117

Kế hoạch cho bộ thu gom rác Go 1.4+:

  • hybrid stop-the-world / bộ sưu tập đồng thời
  • phần dừng lại của thế giới bị giới hạn bởi thời hạn 10ms
  • Các lõi CPU dành riêng để chạy bộ thu đồng thời
  • thuật toán đánh dấu và quét ba màu
  • phi thế hệ
  • không đầm
  • hoàn toàn chính xác
  • phải trả một khoản chi phí nhỏ nếu chương trình di chuyển con trỏ xung quanh
  • độ trễ thấp hơn, nhưng rất có thể thông lượng cũng thấp hơn Go 1.3 GC

Cập nhật bộ thu gom rác Go 1.3 trên Go 1.1:

  • quét đồng thời (dẫn đến thời gian tạm dừng nhỏ hơn)
  • hoàn toàn chính xác

Bộ thu gom rác Go 1.1:

  • đánh dấu và quét (triển khai song song)
  • phi thế hệ
  • không đầm
  • hầu hết chính xác (ngoại trừ khung ngăn xếp)
  • dừng lại thế giới
  • biểu diễn dựa trên bitmap
  • không tốn phí khi chương trình không cấp phát bộ nhớ (nghĩa là: xáo trộn con trỏ xung quanh nhanh như trong C, mặc dù trong thực tế, điều này chạy hơi chậm hơn C vì trình biên dịch Go không tiên tiến như trình biên dịch C như GCC)
  • hỗ trợ trình hoàn thiện trên các đối tượng
  • không có hỗ trợ cho các tài liệu tham khảo yếu

Bộ thu gom rác Go 1.0:

  • giống như Go 1.1, nhưng thay vì chính xác thì bộ thu gom rác lại bảo thủ. GC bảo thủ có thể bỏ qua các đối tượng như byte [].

Thay thế GC bằng một GC khác gây tranh cãi, ví dụ:

  • ngoại trừ các đống rất lớn, không rõ liệu một GC thế hệ tổng thể sẽ nhanh hơn
  • gói "không an toàn" khiến khó triển khai GC chính xác hoàn toàn và nén GC

Ngoài ra bộ thu gom rác hiện tại có độ song song nhất định để nó có thể chạy nhanh hơn trên các hệ thống đa lõi.
uriel

3
@uriel: Có, tôi đã đề cập đến vấn đề này ở mục đầu tiên trong câu trả lời của tôi - văn bản "(triển khai song song)".

Câu trả lời này vẫn còn hiện tại?
Kim Stebel 12/12/12

thu c # rác là chính xác và trong c # như thế nào trong đi bạn có thể có tham chiếu đến thành viên của một tấn công và c # có một chế độ không an toàn, nhưng tôi không chắc chắn làm thế nào nó so sánh để đi an toàn thực
skyde

3
Còn về việc cập nhật câu trả lời này với 1.5.x chỉ để tạo nhật ký lịch sử tốt.
Ismael

32

(Đối với Go 1.8 - Q1 2017, xem bên dưới )

Trình thu gom rác đồng thời Go 1.5 tiếp theo liên quan đến việc có thể "tăng tốc" gc nói.
Đây là một đề xuất được trình bày trong bài báo này có thể phù hợp với Go 1.5, nhưng cũng giúp hiểu được gc trong Go.

Bạn có thể thấy trạng thái trước 1.5 (Stop The World: STW)

Trước Go 1.5, Go đã sử dụng bộ thu thập điểm dừng song song (STW).
Mặc dù bộ sưu tập STW có nhiều nhược điểm, nhưng ít nhất nó cũng có hành vi tăng trưởng đống có thể dự đoán và kiểm soát được.

https://40.media.tumblr.com/49e6556b94d75de1050c62539680fcf9/tumblr_inline_nr6qq8D9FE1sdck2n_540.jpg

(Ảnh từ bài thuyết trình GopherCon 2015 " Go GC: Giải quyết vấn đề độ trễ trong Go 1.5 ")

Núm điều chỉnh duy nhất cho bộ sưu tập STW là “GOGC”, mức tăng trưởng đống tương đối giữa các bộ sưu tập. Cài đặt mặc định, 100%, đã kích hoạt thu gom rác mỗi khi kích thước heap tăng gấp đôi so với kích thước heap trực tiếp như của tập hợp trước:

https://docs.google.com/drawings/image?id=sLJ_JvGfPfPnojLlEGLCWkw&rev=1&h=113&w=424&ac=1

Định thời gian GC trong bộ thu STW.

Go 1.5 giới thiệu một bộ thu đồng thời .
Điều này có nhiều ưu điểm hơn so với thu thập STW, nhưng khó kiểm soát sự tăng trưởng của đống rác vì ứng dụng có thể phân bổ bộ nhớ trong khi trình thu gom rác đang chạy .

https://40.media.tumblr.com/783c6e557b427a5c023520578740eb94/tumblr_inline_nr6qqpmaJx1sdck2n_540.jpg

(Ảnh từ bài thuyết trình GopherCon 2015 " Go GC: Giải quyết vấn đề độ trễ trong Go 1.5 ")

Để đạt được cùng một giới hạn tăng trưởng đống, thời gian chạy phải bắt đầu thu gom rác sớm hơn, nhưng sớm hơn bao nhiêu phụ thuộc vào nhiều biến, nhiều biến trong số đó không thể dự đoán được.

  • Khởi động bộ thu quá sớm và ứng dụng sẽ thực hiện quá nhiều bộ sưu tập rác, gây lãng phí tài nguyên CPU.
  • Khởi động bộ thu quá muộn và ứng dụng sẽ vượt quá mức tăng trưởng đống tối đa mong muốn.

Để đạt được sự cân bằng phù hợp mà không phải hy sinh sự đồng thời đòi hỏi người thu gom rác phải điều chỉnh tốc độ cẩn thận.

Tốc độ GC nhằm mục đích tối ưu hóa theo hai chiều: tăng trưởng đống và CPU được sử dụng bởi bộ thu gom rác.

https://docs.google.com/drawings/image?id=sEZYCf7Mc0E0EGmy4gho3_w&rev=1&h=235&w=457&ac=1

Thiết kế của tốc độ GC bao gồm bốn thành phần:

  1. một công cụ ước tính cho số lượng công việc quét mà một chu kỳ GC sẽ yêu cầu,
  2. một cơ chế để các tác nhân gây đột biến thực hiện khối lượng công việc quét ước tính vào thời điểm phân bổ heap đạt được mục tiêu heap,
  3. một công cụ lập lịch để quét nền khi trình đột biến hỗ trợ sử dụng kém ngân sách CPU và
  4. một bộ điều khiển tỷ lệ cho trình kích hoạt GC.

Thiết kế cân bằng hai quan điểm khác nhau về thời gian: thời gian CPU và thời gian heap .

  • Thời gian CPU giống như thời gian đồng hồ treo tường tiêu chuẩn, nhưng GOMAXPROCSnhanh hơn.
    Nghĩa là, nếu GOMAXPROCSlà 8, thì tám giây CPU vượt qua mỗi giây tường và GC nhận được hai giây thời gian CPU mỗi giây tường.
    Bộ lập lịch CPU quản lý thời gian của CPU.
  • Thời gian heap trôi qua được đo bằng byte và di chuyển về phía trước khi các tác nhân gây đột biến phân bổ.

Mối quan hệ giữa thời gian đống và thời gian tường phụ thuộc vào tỷ lệ phân bổ và có thể thay đổi liên tục.
Mutator hỗ trợ quản lý thời gian qua heap, đảm bảo công việc quét ước tính đã được hoàn thành vào thời điểm heap đạt đến kích thước mục tiêu.
Cuối cùng, bộ điều khiển kích hoạt tạo ra một vòng phản hồi liên kết hai chế độ xem thời gian này với nhau, tối ưu hóa cho cả mục tiêu thời gian đống và thời gian CPU.


20

Đây là việc thực hiện GC:

https://github.com/golang/go/blob/master/src/runtime/mgc.go

Từ các tài liệu trong nguồn:

GC chạy đồng thời với các luồng đột biến, là loại chính xác (hay còn gọi là chính xác), cho phép nhiều luồng GC chạy song song. Nó là một dấu và quét đồng thời sử dụng rào cản ghi. Nó không mang tính thế hệ và không chặt chẽ. Việc phân bổ được thực hiện bằng cách sử dụng kích thước được tách biệt trên mỗi khu vực phân bổ P để giảm thiểu sự phân mảnh trong khi loại bỏ các khóa trong trường hợp phổ biến.


8

Go 1.8 GC có thể phát triển trở lại, với đề xuất "Loại bỏ quét lại ngăn xếp STW"

Kể từ Go 1.7, một nguồn duy nhất còn lại của thời gian dừng lại trên thế giới (STW) không bị giới hạn và có khả năng không quan trọng là quét lại ngăn xếp.

Chúng tôi đề xuất loại bỏ nhu cầu quét lại ngăn xếp bằng cách chuyển sang rào cản ghi kết hợp kết hợp rào cản ghi xóa kiểu Yuasa [Yuasa '90]rào cản ghi chèn kiểu Dijkstra [Dijkstra '78] .

Các thí nghiệm sơ bộ cho thấy điều này có thể làm giảm thời gian STW trong trường hợp xấu nhất xuống dưới 50µs và cách tiếp cận này có thể thực tế để loại bỏ hoàn toàn việc chấm dứt nhãn STW.

Các thông báo là ở đây và bạn sẽ nhìn thấy nguồn có liên quan cam kết là d70b0fe và trước đó.


3

Tôi không chắc, nhưng tôi nghĩ GC (mẹo) hiện tại đã là một song song hoặc ít nhất nó là một WIP. Do đó, tài sản thế giới dừng lại không áp dụng nữa hoặc sẽ không áp dụng trong tương lai gần. Có lẽ ai đó khác có thể làm rõ điều này chi tiết hơn.


7
Nó là điểm dừng của thế giới. GC có khả năng chạy song song sau khi thế giới ngừng hoạt động. Bạn có thể có nghĩa là GC đồng thời.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.