2013-06-13 24 views
8

Tôi đã đấu tranh với vấn đề này trong 3 ngày và hy vọng ai đó có một số thông tin mà tôi chưa gặp phải để trợ giúp tôi ra ngoài (tôi tuyệt vọng!). Để cung cấp một số ngữ cảnh:jQuery (2.0.2) empty() html() Tiêu thụ bộ nhớ Liên tục phát triển

Trình duyệt: IE9.0.8112.16421 (64 bit); Phiên bản jQuery: 2.0.2

Về cơ bản những gì tôi đang làm là thực hiện cuộc gọi ajax đơn giản và truy xuất một số thông tin mà tôi sẽ chèn vào phần tử thông qua trình xử lý thành công. Các dòng có liên quan của mã được hiển thị dưới đây:

var onLoadViewGroupSuccess = function(data) {   
    var target = $("#viewGroupContent"); 
    //for(var i=0;i<1000;i++) { 
     target.empty().html(data); 
    //} 
} 

các mục tiêu tương ứng với thẻ html sau:

<tr id="viewGroupContent">...</tr> 

các chú thích cho vòng lặp trên được thiết kế để phóng đại vấn đề (mà là khó phát hiện thông qua trình kích hoạt nhấp chuột sự kiện duy nhất). Về cơ bản khi vòng lặp được đặt ra, bộ nhớ cho một lời gọi đơn từ 46MB đến ~ 113MB.

Cuộc gọi tiếp theo thể hiện cùng một hành vi với bộ nhớ liên tục phát triển. Ban đầu tôi nghĩ rằng đó là vấn đề với một số trình xử lý sự kiện mà tôi không dọn dẹp được nhưng đã loại trừ điều này vì tôi đã nhận xét hầu như tất cả logic javascript của tôi, vì vậy phần dưới đây về cơ bản là tất cả (tức là không có trình xử lý sự kiện nào, không có đối tượng hoặc chức năng tùy chỉnh) viện dẫn) - tức là không phải là vấn đề đóng cửa.

Di chuyển vòng lặp bên ngoài cuộc gọi ajax (để thực hiện 1000 cuộc gọi ajax) sẽ dẫn đến cùng một cấu hình bộ nhớ (do đó loại bỏ bất kỳ rò rỉ bộ nhớ ajax tối nghĩa nào). Nội dung tôi chèn là thẻ TD chứa một lượng lớn nội dung (ví dụ: các trường hợp của mỗi thẻ HTML mà bạn có thể nghĩ đến bao gồm hình ảnh) để tự hỏi liệu nội dung tôi đang chèn có phải chịu trách nhiệm về rò rỉ không.

Tôi đã đọc một số bài đăng trên blog thú vị về khả năng dọn dẹp của IE sau bản thân bao gồm các bài viết sau có vẻ hứa hẹn nhất (http://com.hemiola.com/2009/11/23/memory-leaks-in-ie8/). Thật không may, không có giải pháp hoặc cách giải quyết cho đến nay.

Tôi đang thua lỗ vì tôi đã xóa ứng dụng của mình xuống phần xương trần và không nhiều bạn có thể làm với $(...).empty().html(...). Rò rỉ bộ nhớ chậm nhưng liên tục ....

Ngoài ra, như một FYI, tôi đã thử các giải pháp không jQuery với phương pháp innerHTML, DOM để loại bỏ hàng trong bảng và xây dựng lại rồi chèn nội dung ajax vào bảng các ô, di chuyển nội dung bị hủy vào thùng rác DIV và sau đó gọi innerHTML, tất cả đều không có sẵn, và trong nhiều trường hợp làm cho rò rỉ tệ hơn ...

+1

Vui lòng thêm một số đoạn văn bản để làm cho bức tường văn bản này dễ đọc hơn. –

+0

@FelixKling Hy vọng điều đó tốt hơn ... –

+0

Việc sử dụng '.empty()' trước '.html()' là gì? Không phải '.html()' Thay đổi toàn bộ html làm rỗng DOM trước khi thêm giá trị? –

Trả lời

0

Xem nhận xét cuối cùng của tôi ở trên, nó xuất hiện những gì tôi cảm nhận Rò rỉ bộ nhớ chỉ là các đối tượng đang chờ GC nhưng do tính chất của ứng dụng của tôi (tức là 99% các điều hướng được thực hiện thông qua ajax) IE đơn giản không bao giờ thực hiện một GC đầy đủ cho đến khi điều hướng trang thực sự xảy ra (tức là window.top unloaded) . Xảy ra để thông báo điều này khi đăng xuất và đột nhiên bộ nhớ cho ví dụ IE của tôi plummets từ 200-63MB ... Tôi đã thử bằng tay gọi một GC (nhưng điều này không xuất hiện để làm việc ...). Vì vậy, bây giờ, sẽ thay thế mọi điều hướng ajax thứ n với điều hướng trang thực tế để dọn dẹp mọi thứ ... không lý tưởng, nhưng sẽ làm cho thời điểm này cho đến khi tôi có thể tìm ra cách tốt hơn.

0

Hãy thử cập nhật lib của jQuery, chỉ để kiểm tra xem có một số cải tiến về điều đó không.

Và xóa hàm "empty()". Nó không phải là không cần thiết, bởi vì, html() sẽ ghi đè tất cả các ớn lạnh. Điều này có thể giúp bạn tránh sử dụng bộ nhớ.

0

Bạn đã cố gắng đưa dữ liệu đã nhận vào phần tử trình bao mà bạn loại bỏ trong lần lặp tiếp theo?

var onLoadViewGroupSuccess = function(data) { 
    var target = $("#viewGroupContent"); 
    //for(var i=0;i<1000;i++) { 
     target.find('>div').remove(); 
     target.append($('<div>').html(data)); 
    //} 
} 

Nếu có loại rò rỉ nào liên quan đến clean() API, bạn sẽ loại bỏ nó.

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