2008-11-09 53 views
7

Tôi đang làm việc trên một ứng dụng web được thiết kế để hiển thị một loạt dữ liệu được cập nhật định kỳ với AJAX. Kịch bản sử dụng chung sẽ là một người sử dụng sẽ để nó mở cửa cả ngày và liếc nhìn nó ngay bây giờ và sau đó.Ngăn chặn rò rỉ bộ nhớ AJAX

Tôi đang gặp sự cố khi dấu chân bộ nhớ trình duyệt đang phát triển chậm theo thời gian. Điều này đang xảy ra trong cả Firefox và IE 7 (Mặc dù không có trong Chrome). Sau một vài giờ, nó có thể khiến IE7 có dấu chân ~ 200MB và FF3 để có dấu chân ~ 400MB.

Sau nhiều lần kiểm tra, tôi đã phát hiện thấy rò rỉ bộ nhớ chỉ xảy ra nếu các cuộc gọi AJAX đang được trả lời. Nếu máy chủ không phản hồi bất cứ điều gì, tôi có thể để trang mở cửa hàng giờ và dấu chân sẽ không phát triển.

Tôi đang sử dụng mẫu thử nghiệm cho các cuộc gọi AJAX của mình. Vì vậy, tôi đoán có một vấn đề với việc gọi lại onSuccess tạo ra những rò rỉ bộ nhớ.

Có ai có bất kỳ mẹo nào về ngăn ngừa rò rỉ bộ nhớ với mẫu thử nghiệm/AJAX không? Hoặc bất kỳ phương pháp nào về cách khắc phục sự cố này?

EDIT: phát hiện vấn đề nằm trong thư viện đồ thị js tôi đang sử dụng. Có thể được nhìn thấy here.

Trả lời

10

Điều quan trọng nhất bạn có thể xem là các sự kiện và cách bạn chỉ định chúng.

Ví dụ, lấy kịch bản này (vì bạn đã không cung cấp một):

<div id="ajaxResponseTarget"> 
    ... 
</div> 
<script type="text/javascript"> 
    $(someButton).observe('click', function() { 
     new Ajax.Updater($('ajaxResponseTarget'), someUrl, { 
      onSuccess: function() { 
       $$('#ajaxResponseTarget .someButtonClass').invoke('observe', 'click', function() { 
        ... 
       }); 
      } 
     }); 
    }); 
</script> 

này sẽ tạo ra một rò rỉ bộ nhớ, bởi vì khi #ajaxResponseTarget được cập nhật (nội bộ, Prototype sẽ sử dụng innerHTML) các yếu tố với click các sự kiện sẽ bị xóa khỏi tài liệu mà không có sự kiện nào bị xóa. Lần thứ hai bạn nhấp vào someButton, khi đó bạn sẽ có gấp đôi số trình xử lý sự kiện và bộ sưu tập rác không thể xóa tập đầu tiên.

Một cách để tránh điều này là sử dụng đoàn sự kiện:

<div id="ajaxResponseTarget"> 
    ... 
</div> 
<script type="text/javascript"> 
    $('ajaxResponseTarget').observe('click', function(e) { 
     if(e.element().match('.someButtonClass')) { 
      ... 
     } 
    }); 
    $(someButton).observe('click', function() { 
     new Ajax.Updater($('ajaxResponseTarget'), someUrl); 
    }); 
</script> 

Do cách sự kiện DOM làm việc, "click" trên .someButtonClass sẽ cháy cũng trên #ajaxResponseTarget, và thử nghiệm làm cho nó chết đơn giản để xác định yếu tố nào là mục tiêu của sự kiện. Không có sự kiện nào được gán cho các phần tử trong phạm vi#ajaxResponseTarget, vì vậy không có cách nào để thay thế nội dung của nó thành sự kiện mồ côi từ các mục tiêu bên trong.

+0

+1 Thông tin tốt, mặc dù tôi không bao giờ tạo bất kỳ sự kiện mới nào sau khi tải trang ban đầu. Vẫn cố gắng tìm ra những gì tôi đang làm sẽ gây ra vấn đề. –

+1

Nếu bạn không tạo bất kỳ sự kiện nào ... tại sao bạn chấp nhận điều này làm câu trả lời? – Sean

-3

Tôi có thể sai nhưng có vẻ như bạn đang tạo bao đóng xung quanh đối tượng phản hồi. Mỗi đối tượng phản hồi sẽ khác nhau, kết quả là dấu chân bộ nhớ tăng lên.

+0

Bạn có thể giải thích một chút không? Xin lỗi tôi không chắc chắn những gì bạn có nghĩa là "đóng cửa xung quanh đối tượng phản ứng". Bạn có nghĩa là một chức năng? –

+0

http://en.wikipedia.org/wiki/Closure_(computer_science) –