Điều chỉnh trình thu gom rác của nodejs
Trước đây, khi bạn đang viết một chương trình, bạn sẽ làm những việc kỳ lạ như malloc hoặc tự do quản lý bộ nhớ chương trình của mình Show Trong các ngôn ngữ hiện đại, Garbage Collector (GC) xử lý tất cả những điều này cho bạn. Điều này cũng đúng với NodeJS sử dụng V8 đến GC và thực thi tất cả mã javascript Hiểu rõ về các cơ chế đằng sau GC có thể giúp bạn tránh được cơn ác mộng của nhà phát triển cuối cùng; . Hơn nữa, giám sát GC có thể giúp bạn tối ưu hóa ứng dụng của mình Một cơn ác mộng trông như thế nào. Tại sao bạn nên quan tâm đến số liệu GC?Tôi làm việc tại Voodoo, một công ty của Pháp chuyên sản xuất trò chơi điện tử trên điện thoại di động. Chúng tôi gặp rất nhiều vấn đề về hiệu suất, tính khả dụng và khả năng mở rộng do lưu lượng truy cập quá lớn mà cơ sở hạ tầng của chúng tôi hỗ trợ (hàng tỷ sự kiện/yêu cầu mỗi ngày…… không đùa đâu. ). Trong cài đặt này, mọi khía cạnh của phát triển web đều quan trọng và mọi quyết định đều có thể có tác động lớn đến hoạt động kinh doanh của chúng tôi Hầu hết thời gian, khi làm việc trên một API hoặc dự án có lưu lượng truy cập thấp, chúng tôi không nhận ra mình có thể thực hiện bao nhiêu điều chỉnh hoặc cải tiến. Mặt khác, khi lưu lượng truy cập tăng lên, tất cả những sơ sót trước đó có thể phải trả giá đắt. Vào năm 2009, Amazon phát hiện ra rằng cứ 100 mili giây độ trễ khiến họ mất 1% doanh số Vì vậy, việc hiểu rõ các cơ chế của GC cùng với việc giám sát tốt các chỉ số của nó có thể giúp bạn xây dựng một ứng dụng mạnh mẽ hơn, đặc biệt là với các dự án có lưu lượng truy cập cao thuật toán GCTrình thu gom rác không nhất thiết phải dọn dẹp bộ nhớ theo cùng một cách mỗi lần. Với V8 có 2 thuật toán chính. Rác và Đánh dấu/Quét/Thu gọn nhặt rácThuật toán này có thể chạy nhiều lần và dọn dẹp một lượng nhỏ bộ nhớ. Khi theo dõi các chu kỳ GC, có thể bạn sẽ thấy thuật toán nhặt rác chạy nhiều nhất
Như thể hiện trong hình trên, một chu kỳ nhặt rác về cơ bản sao chép bộ nhớ trong không gian “đến” vào không gian “từ”, sau đó di chuyển tất cả các đối tượng “còn sống” trở lại không gian “đến”. Nếu một số đối tượng quá cũ, chúng sẽ được chuyển đến “không gian cũ” Khi thuật toán kết thúc, “to space” chỉ chứa các đối tượng còn sống nên được giữ lại. Loại chu trình GC này có những hạn chế quan trọng vốn có trong thuật toán. di chuyển các đối tượng vào bộ nhớ. Đây là lý do tại sao nó chỉ được sử dụng trên không gian mới để dọn dẹp bộ nhớ thường xuyên (nhưng nhỏ) Đánh dấu / Quét / Thu gọnThuật toán này dựa trên một cách tiếp cận đơn giản. đánh dấu các đối tượng trong bộ nhớ để biết đối tượng nào còn “sống”, sau đó quét bộ nhớ để dọn sạch các đối tượng “chết” (không sử dụng). Và cuối cùng, bộ nhớ nhỏ gọn để tối ưu hóa nó giai đoạn đánh dấu
Về cơ bản, hệ thống đánh dấu này có thể được tóm tắt như thế này
Để hiểu rõ hơn về giai đoạn này, thật hữu ích khi xem trí nhớ như một cái cây. Mỗi nút đại diện cho một đối tượng trong bộ nhớ và mỗi nhánh đại diện cho một tham chiếu giữa các đối tượng Ban đầu, tất cả các nút “gốc” sẽ tự động được gắn cờ màu xám vì GC đã biết về chúng. Trong thế giới NodeJs, một nút gốc thường là đối tượng “toàn cầu” hoặc “quy trình” Khi GC đã phát hiện ra tất cả các nút, tất cả chúng sẽ được đánh dấu bằng màu đen…… hoặc không. Tất cả các đối tượng “trắng” còn lại sẽ bị xóa trong giai đoạn quét Ví dụ về trạng thái bộ nhớ ở cuối giai đoạn đánh dấugiai đoạn quét
Toàn bộ mục đích của giai đoạn đánh dấu trước đó là đánh dấu các đối tượng mà bộ nhớ của chúng có thể được giải phóng trong giai đoạn này giai đoạn nhỏ gọn
Một tối ưu hóa khác của bộ nhớ. GC không chỉ loại bỏ các đối tượng không sử dụng mà còn cố gắng sắp xếp bộ nhớ để cho phép đọc bộ nhớ nhanh hơn Sau giai đoạn quét, bộ nhớ được giải phóng có thể được phân tách bằng các khối bộ nhớ vẫn đang được sử dụng Tác động pha nhỏ gọn Có gì mới trong Onirocco?Dọn dẹp và nén bộ nhớ không phải là những cải tiến và tối ưu duy nhất mà V8 có thể làm cho bạn. Cơ chế ban đầu đằng sau các chu trình GC như sau. chương trình của bạn bị dừng để GC có thể thực hiện công việc của mình. k. hội chứng “dừng thế giới” Dừng lại thế giớiVì vậy, đây là cách nhóm V8 xử lý nó Đầu tiên, giới thiệu “đánh dấu gia tăng”Giai đoạn “đánh dấu” mất quá nhiều thời gian? Đánh dấu gia tăng Tất nhiên, tổng thời gian của tất cả các chu trình GC vẫn như cũ, nhưng luồng chính có sẵn thường xuyên hơn để thực thi mã của bạn. Nó mang lại cảm giác tăng tính trôi chảy trong quá trình thực hiện chương trình của bạn lười quétCòn giai đoạn càn quét thì sao? . ừ thì cũng thế thôi nhưng gọi là lười quét
Giai đoạn càn quét có thể được thực hiện ngay lập tức… hoặc có thể bị trì hoãn. Nếu dung lượng bộ nhớ trống đủ để thực thi mã của bạn, tại sao phải thực hiện giai đoạn quét toàn bộ ngay lập tức? Nó cũng có thể được thực hiện song song. Hãy xem làm thế nào đồng thờiCác phiên bản mới nhất của V8 có thể thực hiện các chu kỳ GC trên nhiều luồng khác nhau. Bạn có thể hưởng lợi từ cơ chế phân tách nhưng với cách tiếp cận song song, giảm thời gian GC toàn cầu cách tiếp cận đồng thờiNhưng bạn vẫn thấy một loại nguyên tắc “dừng thế giới” ở đây. Có cách nào để thoát khỏi nó? . Và nó được gọi là "song song" Song song, tương đôngKhi có thể, V8 có thể thực hiện các thao tác GC song song với mã của bạn cách tiếp cận song songV8 có thể làm gì? . )Trên thực tế, V8 chọn cách tốt nhất để quản lý bộ nhớ của bạn và thực hiện các thao tác GC. Nó có thể áp dụng tất cả các cơ chế trước đó cùng nhau, như hình ảnh bên dưới tổng hợp Trường hợp thực tế Làm cách nào để giám sát bộ nhớ và GC?mô-đun V8
Có 2 phương pháp quan trọng trong mô-đun này
đầu ra cơ bản mô-đun gc-stats
Trước hết, mô-đun này không phải là mô-đun tích hợp trong nodejs. Vì vậy, bạn cần phải cài đặt nó npm install gc-stats Mô-đun này cho phép bạn nghe “số liệu thống kê” về sự kiện đặc biệt để truy xuất dữ liệu chu kỳ GC triển khai và đầu ra gc-statsTùy chọn V8V8 có thể in một số thông tin có giá trị về trạng thái của nó và đặc biệt là về cách hoạt động của bộ thu gom rác. Để hiển thị dữ liệu bổ sung này, bạn phải chuyển sang các đối số V8 (so với NodeJs) trước khi bắt đầu ứng dụng của mình node --trace_gc app.js Một trong những tùy chọn thú vị nhất để lấy một số dữ liệu GC là --trace_gc. Một đầu ra điển hình sẽ trông như thế này — đầu ra dấu vết_gcCuối cùng, bạn có thể tìm thấy danh sách đầy đủ các tùy chọn V8 tại đây https://gist.github.com/listochkin/10973974 APMCuối cùng nhưng không kém phần quan trọng. đừng bao giờ quên sử dụng apm (Quản lý hiệu suất ứng dụng) để theo dõi việc sử dụng bộ nhớ của bạn trong thời gian thực Một số trong số chúng cũng có thể hiển thị một vài số liệu về trình thu gom rác, xem hình ảnh bên dưới Thật không may, trình độ nghệ thuật hiện tại cho thế giới giám sát không thực sự cập nhật với trình thu gom rác NodeJs. Thật vậy, sau khi thử nghiệm rất nhiều công cụ apm, tôi thấy rằng hầu hết chúng không hiển thị tất cả dữ liệu có sẵn và đa số thậm chí không có tính năng này Phần kết luậnHiểu về bộ thu gom rác và tại sao vai trò của nó là trung tâm trong quản lý bộ nhớ chương trình của bạn là rất quan trọng nếu bạn muốn nắm vững những gì NodeJ và V8 có thể làm cho bạn. Theo dõi và gỡ lỗi các chu kỳ của GC và trạng thái bộ nhớ có thể giúp bạn tìm ra một số tắc nghẽn về hiệu suất và ngăn ngừa sự cố máy chủ Bạn cũng nên theo dõi và thiết lập một số cảnh báo tự động trên các chỉ số của GC, chẳng hạn như thời lượng trung bình của chu kỳ GC (không được vượt quá vài mili giây) hoặc tần suất tạm dừng của GC Bạn có thể tìm thấy bài nói gốc của tôi ở đây. https. // tài liệu. Google. com/presentation/d/17PXOZXBgdJHqBZlbULHg70_hVFLrNx9T34rB9bLDn2M/edit#slide=id. g3ffed3592f_0_0 |