Câu hỏi Làm thế nào để tránh tăng nhanh bộ nhớ trong quá trình nhặt rác gc?


Tôi có một ứng dụng được xây dựng dựa trên việc khôi phục. Tôi không có rò rỉ bộ nhớ, tuy nhiên tôi có tăng trưởng bộ nhớ lớn trong quá trình nhặt rác gc, sau đó đi kèm trọng lượng nặng đánh dấu quét gc và làm sạch bộ nhớ.

Nó ảnh hưởng đến hiệu suất của ứng dụng của tôi.

[2268]   266859 ms: Scavenge 61.5 (119.5) -> 46.0 (119.5) MB, 2.2 ms [allocation failure].
[2268]   267084 ms: Scavenge 63.7 (119.5) -> 48.3 (119.5) MB, 6.2 ms [allocation failure].
[2268]   267289 ms: Scavenge 66.0 (119.5) -> 50.6 (119.5) MB, 2.6 ms [allocation failure].
[2268]   267504 ms: Scavenge 68.3 (119.5) -> 52.8 (119.5) MB, 2.4 ms [allocation failure].
[2268]   267700 ms: Scavenge 70.5 (119.5) -> 55.1 (119.5) MB, 2.7 ms [allocation failure].
....

[2268]   275913 ms: Scavenge 154.2 (183.5) -> 138.8 (183.5) MB, 2.4 ms [allocation failure].
[2268]   276161 ms: Scavenge 157.5 (185.5) -> 142.1 (185.5) MB, 2.7 ms (+ 2.4 ms in 18 steps since last GC) [allocation failure].
[2268]   276427 ms: Scavenge 159.8 (187.5) -> 144.3 (187.5) MB, 2.5 ms (+ 36.3 ms in 236 steps since last GC) [allocation failure].
[2268]   276494 ms: Mark-sweep 147.7 (188.5) -> 43.7 (121.5) MB, 20.1 ms (+ 45.1 ms in 298 steps since start of marking, biggest step 0.5 ms) [GC interrupt] [GC in old space requested].

Loại hành vi này xảy ra khi tôi cố truy cập url không tồn tại

ab -c 100 -n 10000000 -k http://localhost:1337/invalid/url

Tôi thực sự không thể sử dụng bộ kiểm tra nút để theo dõi nguyên nhân gây ra sự tăng trưởng bộ nhớ dữ dội như vậy vì nó sẽ yêu cầu đầy đủ gc trước khi chụp ảnh heap.

Các tùy chọn của tôi để theo dõi nguyên nhân gây ra sự tăng trưởng bộ nhớ nhanh như thế nào?

Làm thế nào để tìm ra những vật thể nào tồn tại được các vật nhặt rác nhưng không tồn tại được gc đánh dấu?

Cảm ơn,

CẬP NHẬT 1 Vì vậy, không có cách nào để xem nội dung nhặt rác ở độ tuổi trung niên. Đây là gợi ý, nếu bạn thấy tăng bộ nhớ nhanh trong quá trình nhặt rác nhưng sau đó nó đột nhiên giảm xuống với dấu và quét thì điều đó có nghĩa là mã của bạn tạo dữ liệu trong không gian rộng lớn. Ví dụ: dấu vết ngăn xếp dài. Phục hồi tạo ra các dấu vết ngăn xếp khổng lồ cần được vô hiệu hóa trong sản xuất.


14
2017-08-28 12:47


gốc




Các câu trả lời:


Bạn có thể thử chạy tập lệnh Node bằng tùy chọn -–expose-gc:

node --expose-gc script.js

Điều này cho phép kích hoạt bộ sưu tập rác thủ công từ bên trong JS:

global.gc();

Khi thu thập rác được thực thi theo cách thủ công, bạn có thể áp dụng kỹ thuật chụp nhanh nhiều lần:

  • lấy một Snap trước, một Snap sau GC
  • sau đó áp dụng tối ưu hóa
  • sau đó một Snap trước, một Snap sau GC

Các ảnh chụp nhanh cho phép theo dõi những gì gây ra sự tăng trưởng bộ nhớ. Mục đích là để có kết quả tốt hơn về "Snap after GC" thứ hai, khi so sánh với "Snap sau GC" đầu tiên.


3
2017-08-28 13:14



Xin lỗi vì câu hỏi ngớ ngẩn, nhưng làm cách nào để chụp nhanh mà không gọi gc? - Vlad Miller
Sau khi thực hiện ứng dụng nút của bạn, hãy kích hoạt thanh tra nút và kết nối với http://127.0.0.1:8080/debug?port=5858 (hoặc máy chủ lưu trữ của bạn thay vì localhost) với ví dụ: Chrome Dev Tools và sau đó đi đến tab "Hồ sơ". Bạn sẽ tìm thấy "Take Heap Snapshot" và "Record Heap Allocation" ở đó. - Jens A. Koch
Vâng, đó là những gì tôi đang thực hiện. Tôi thấy trong nhật ký trước khi thực hiện đầy đủ ảnh chụp, nó chạy đầy đủ gc - Vlad Miller
Garbage Collection chỉ bị ép buộc tự động khi chụp Heap Snapshot. Nói cách khác: "Ghi lại phân bổ đống". Nó sẽ chụp nhanh trong suốt quá trình ghi và sau đó là một snap cuối cùng ở cuối. developers.google.com/web/tools/profile-performance/… - Jens A. Koch
Thật lạ lùng, tôi vẫn chỉ thấy gc Mark-sweep được gọi trong Heap Allocations snapshot - Vlad Miller


Kiến thức tốt nhất của tôi không có cách nào đơn giản để xem nội dung trung niên. Tuy nhiên, nếu bạn thấy tăng bộ nhớ nhanh trong quá trình nhặt rác và sau đó giảm đột ngột khi đánh dấu và quét diễn ra thì điều này thường có nghĩa là mã của bạn tạo ra các đối tượng trong không gian đống lớn. Ví dụ: chuỗi dài.

Rectify tạo ra các dấu vết stack khổng lồ với mỗi đối tượng Error đủ lớn để không vừa với không gian mới và do đó bị bỏ qua bởi dấu và quét.


0
2017-11-18 01:09