nói dối e blog

Phân Tích Mã Nguồn Lua GC (4)

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.

Phân Tích Mã Nguồn Lua GC (5)

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.

Phân Tích Mã Nguồn Lua GC (Phần 1)

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.

Thực Hành Cơ Bản Với Ngôn Ngữ Lập Trình Go (1)

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.

Thực Hành Lập Trình Go (Phần 2)

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 pushpop với giao diện như sau:

1
2
3
4
type myMap interface {
  push(key string, e interface{}) interface{} 
  pop(key string) interface{}
}
Yêu cầu chi tiết
  • Khi thực hiện push:
    • Nếu key đã tồn tại trong map → trả về giá trị cũ
    • Nếu key chưa tồn tại → thêm cặp key-value mới và trả về nil
  • Khi thực hiện pop:
    • Trả về giá trị tương ứng với key
    • Xóa cặp key-value khỏi map sau khi trả về
Phiên bản sử dụng Mutex (sync.Mutex)

Đâ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:

0%