7

Tôi có một ứng dụng gọi nhân viên web sau khi nhấp vào nút. Các tính toán được chuyển đến công nhân để giảm giao diện người dùng và làm cho nó đáp ứng với hành động của người dùng trong khi tính toán đang được thực hiện.Rò rỉ bộ nhớ có thể xảy ra khi sử dụng Nhân viên Web (Bộ thu gom rác)

Mọi thứ đều ổn và sau khoảng 0.8-1.5s, nhân viên sẽ gửi phản hồi. Trong worker.onmessage tôi thực hiện tất cả các hành động DOM cần thiết. Nhưng sau khi GC này xuất hiện và thực tế chặn giao diện người dùng trong 2 giây trở lên tùy thuộc vào CPU. Điều này thực sự gây nhầm lẫn cho tôi, bởi vì chặn UI là những gì tôi muốn ngăn chặn.

Dưới đây là ảnh chụp màn hình của giao diện điều khiển tab timeline/bộ nhớ: http://i.imgur.com/zUoHa.jpg

Như bạn có thể xem các sự kiện GC xảy ra chỉ sau khi tất cả thao tác DOM. Trên thực tế chỉ có một sự kiện repaint (DocumentFragment được sử dụng).

js chính mã:

var sortWorker = new Worker('js/contactsorter.js'); 
sortWorker.onmessage = function(e) { 
    var messages = []; 
    e.data.forEach(function(userDoc) { 
     var contactSection = _drawContact(userDoc); 
     messages.push(contactSection); 
    }); 

    meta.append(messages); // this actually appends document fragment as a child 
}; 

sortWorker.postMessage(postMessageData); 

contactsorter.js (công nhân):

onmessage = function(e) { 
    var uid, output = [], usersStat = {}; 

    // calculations... 

    postMessage(output); 
    close(); 
}; 

Có cách nào để tránh những sự kiện GC ở nơi này hay không?

UPD: có vẻ như với tôi rằng thời gian của sự kiện GC phụ thuộc vào số lượng dữ liệu đã được gửi tới công nhân. UPD2: Sau khi tắt máy và khởi động các sự kiện GC xảy ra chỉ hai lần do đó ngăn chặn giao diện người dùng trong ít hơn một giây. Hm?

+0

Các vật thể lớn đến mức nào? Bao nhiêu? Chúng ta đang nói về loại số nào? Bạn đang tạo nút DOM nào? Quy mô sự kiện GC có tuyến tính với số lượng liên hệ được sắp xếp không? –

+0

JSON.stringify nói rằng đó là khoảng 2M.Đây là những đối tượng có đối tượng như con cái của họ. Sau khi phản hồi của nhân viên (nó xuất ra một mảng), tôi tạo DocumentFragment và gắn thêm khoảng. 400 "div" yếu tố cho nó. Sau đó, tôi nối thêm đoạn mã vào DOM. Về câu hỏi cuối cùng - tôi cần phải viết lại mã của mình để thực hiện bài kiểm tra, vì vậy tôi sẽ bình luận sau này một chút.Btw: UPD mới –

+0

Về câu hỏi cuối cùng: không, sự kiện GC không quy mô theo số lượng dữ liệu. Hơn nữa, tôi thậm chí không thể tìm thấy nó trên dòng thời gian http://i.imgur.com/psGpr.png mặc dù trong khoảng thời gian này giao diện người dùng đang được định giờ. –

Trả lời

3

Một điều cần nhớ với các Web Worker, và đặc biệt là khi bạn đã sử dụng chúng trong ví dụ của bạn, là bạn đang nhân bản đối tượng khi bạn gửi nó cho người lao động. Vì vậy, cho phép chạy qua chuyện này với một ví dụ ngớ ngẩn:

  1. Làm cho đối tượng lớn (bạn nói 2M trong một bình luận ... wtf ... wow) - 2M được phân bổ trong chủ đề chính
  2. Đăng lên công nhân, 2M trong thread chính vẫn còn, cộng với bất cứ điều gì thêm được tạo ra như lông tơ trong thread chính để JSONify đối tượng của bạn/mảng, sau đó tắt cho công nhân nơi 2M trong công nhân yay
  3. Chug trên sucker trong công nhân ... ở đây 2M + trong chủ đề chính chỉ là ngồi quanh chờ GC, có thể xảy ra bây giờ, có thể không ... GC kích hoạt sau một số lượng nhất định của các đối tượng thế hệ mới đạt ngưỡng ... như nói sau hoặc trong quá trình tạo ra một tấn các đối tượng mới và các yếu tố dom: D
  4. Công nhân phản hồi lại bằng một tin nhắn, giả sử 2M hiện đã được tạo thành một lần nữa trong chủ đề chính cho 2M mới (yay), cộng với bất kỳ đối tượng bộ nhớ fluff nào cần để định dạng đối tượng ... bạn sẽ thấy nó đang ở đâu.

Vì bạn nói rằng đây là một ứng dụng chrome (comment khác), thì có lẽ bạn có thể tái cấu trúc mã của bạn để tận dụng Transferable Objects để tránh các đối tượng nhân bản tạo ra các đối tượng tạm thời, vv Course, sử dụng đối tượng chuyển nhượng bạn 'd phải tái cơ cấu như một bộ đệm mảng và đó là một phép thuật đen tối của chính nó.

+0

* "bạn đã nói 2M trong một nhận xét ... wtf ... wow" * - Lớn hơn nhiều so với các ứng dụng như đồ họa, âm thanh hoặc phần mềm phân tích. Tôi đang đi qua mảng 12 GB (!) Ở đây mà không có vấn đề bằng cách sử dụng transferables. –

+0

@JohnWeisz - Đồng ý, gần đây tôi cũng thường xuyên sử dụng các đối tượng lớn hơn với WebAudio vv Nhưng trong cách trở lại máy vào cuối năm 2013 có vẻ như rất nhiều. Tôi nghĩ rằng vấn đề thực tế của anh ta có nhiều cách hơn để tạo ra vô số các đối tượng tạm thời và là một phần của vòng lặp hay người lập bản đồ của anh ấy ... không nói đến những gì anh ta làm trong DOM. –

Các vấn đề liên quan