Phân Tích Mã Nguồn Của Lua GC (3)
Phân tích mã nguồn của Lua GC (3)
Phân tích mã nguồn của Lua GC (3)
Hôm nay chúng ta sẽ tìm hiểu quá trình đánh dấu (mark) được thực hiện như thế nào.
Tất cả các quy trình GC đều bắt đầu từ hàm singlestep
. Đây là một máy trạng thái đơn giản, luân phiên chuyển đổi giữa các trạng thái liên tiếp nhau. Trạng thái được lưu trữ trong trường gcstate
của global state
. Hai trạng thái đầu tiên liên quan trực tiếp đến quá trình đánh dấu.
Hôm nay chúng ta hãy cùng tìm hiểu về write barrier – một thành phần quan trọng trong cơ chế thu gom rác của Lua. Trong quá trình quét bộ nhớ, do việc xử lý được chia thành nhiều giai đoạn, sẽ có những lúc các đối tượng vừa được đánh dấu thành màu đen nhưng lại bị sửa đổi lại – khiến chúng cần phải được đánh dấu lại. Để giải quyết vấn đề này, hệ thống phải thiết lập một rào chắn ghi (write barrier) mỗi khi có thao tác chỉnh sửa đối tượng. Những thay đổi này sẽ đảm bảo các đối tượng liên quan được đánh dấu màu chính xác, hoặc được ghi lại vào danh sách để xử lý ở giai đoạn atomic cuối cùng của quá trình đánh dấu.
Gần đây, trong quá trình vận hành môi trường Lua với lượng dữ liệu lớn, tôi nhận thấy hoạt động thu gom rác (GC) đang chiếm dụng tới khoảng 20% tổng thời gian CPU. Điều này khiến tôi quyết tâm tối ưu hóa vấn đề này. Để làm được điều đó, trước tiên phải hiểu rõ bản chất thuật toán và cơ chế triển khai GC của Lua. Dù đã từng nghiên cứu mã nguồn Lua trước đây, nhưng do sự thay đổi giữa các phiên bản mã nguồn, tôi buộc phải thực hiện lại toàn bộ quá trình này. Lần này, tôi đã tập trung phân tích kỹ lưỡng mã nguồn phiên bản Lua 5.1.4. Từ hôm nay, tôi sẽ ghi chép chi tiết quá trình nghiên cứu này thành chuỗi bài viết. Việc đọc mã nguồn đã chiếm trọn 1 ngày làm việc của tôi, nhưng việc biên soạn thành bài viết có thể còn tốn nhiều thời gian hơn nữa. Tôi sẽ chia sẻ nội dung này thành nhiều kỳ trên blog cá nhân.
Chạm ngõ lập trình Go (Kỳ 1) Sáng nay bỗng nảy ra ý tưởng xây dựng một dịch vụ truyền tải tập tin nhỏ gọn theo nhu cầu cá nhân. Tôi nhận ra rằng việc chỉ nói suông về các ý tưởng công nghệ giống như kiểu “ngồi trên lưng ngựa không biết đường đi” - một hình ảnh ẩn dụ tôi thường dùng khi phê phán lối làm việc thiếu thực chất. Đặc biệt trong lĩnh vực sản phẩm mạng, việc chỉ có các “quản lý sản phẩm chuyên nghiệp” ngồi mơ mộng mà không chịu tự tay triển khai thì giống như việc xây nhà không bản vẽ chi tiết.
Tiếp nối từ hôm qua, chúng ta sẽ cùng xây dựng một cấu trúc map đặc biệt hỗ trợ hai thao tác push
và pop
với giao diện như sau:
|
|
push
:
key
đã tồn tại trong map → trả về giá trị cũkey
chưa tồn tại → thêm cặp key-value mới và trả về nil
pop
:
key
Đây là cách tiếp cận truyền thống nhưng hiệu quả để đảm bảo an toàn luồng (thread-safe) trong môi trường đa luồng: