2014-10-05 17 views
12

Đã tìm kiếm một thời gian trong lưu trữ và trên 'net cho một câu trả lời, nhưng không thực sự tìm thấy một, chỉ cần bit và miếng. Có vẻ như có rất nhiều bài viết được đề xuất, nhưng không ai trong số đó có câu trả lời.

Tôi có một chỉ thị phức tạp đang sử dụng phạm vi: đúng. Nó thực sự là phiên bản 2.x ng-grid mới nhất mà tôi đang cố gắng để viết mã dọn dẹp, vì nó chỉ là bộ nhớ bị rò rỉ như điên, và ứng dụng của chúng tôi là "bị mắc kẹt" với nó bây giờ. Đây là the plunk that demos the problem. Khi bạn nhấp qua lưới và kiểm tra heap snapshot sau đó, bạn sẽ thấy một vài đối tượng ngGrid "chưa được sắp xếp". Chúng chỉ được lắng nghe bởi người nghe theo phạm vi của chỉ thị.

Khi tôi thay đổi trạng thái (sử dụng ui.route mới nhất) bằng cách nhấp qua nhiều lưới (tiểu bang), phạm vi chỉ thị của lưới IS nhận được sự kiện hủy $. Trình xử lý đang hoạt động. Tuy nhiên, phạm vi chính nó là không nhận được $ destroy() được gọi trên nó. Tôi thấy trong heap snapshot rằng phạm vi của chỉ thị vẫn giữ nguyên các phần tử thông qua $$ listeners. Ngoài ra, phạm vi. $$ bị hủy chưa được đặt.

Tuy nhiên, phạm vi. prototypeIS bị hủy. Và bởi vì nó là, tôi thậm chí không thể gọi $ phạm vi $ phá hủy từ $ on-$ phá hủy xử lý của chỉ thị, từ những năm $ proto tiêu diệt() gọi thay đổi định nghĩa của $ phá hủy để noop:.

ngGridDirectives.directive('ngGrid', ['$compile', '$filter', '$templateCache', '$sortService', '$domUtilityService', '$utilityService', '$timeout', '$parse', '$http', '$q', 
    function($compile, $filter, $templateCache, sortService, domUtilityService, $utils, $timeout, $parse, $http, $q) { 
    var ngGridDirective = { 
    scope: true, 
    compile: function() { 
     return { 
     pre: function($scope, iElement, iAttrs) { 
      $(iElement).on('$destroy', function cleanupElementNgGrid() { 
       $timeout(function() { 
       $scope.$destroy(); 
       $scope.destroyedByForce = true; 
       console.log("I destroyed it."); 
       },4000); 
      }); 
     ... 

Thiết lập phạm vi $$ listeners = {} với thời gian chờ $ 2000 (để dành thời gian cho chỉ thị hoàn thành việc dọn dẹp trong trình nghe phá hủy $- dường như hoạt động, nhưng cảm thấy sai khi munge với nội bộ và đôi khi . không đủ dài cho trình duyệt để hoàn tất việc dọn dẹp Nó chỉ là một công việc xung quanh/kludge

tôi cũng đã cố gắng này:.

Vậy điều gì đang ngăn chỉ thị của tôi phạm vi f rom nhận $ destroy() tự động gọi vào nó?

Lúc đầu, tôi nghĩ đó là vì chúng tôi sử dụng phạm vi: đúng trong các tùy chọn chỉ thị, vì phạm vi proto dường như đã bị hủy. Vì vậy, tôi đã viết a plunk to try that theory out. Nhưng với plunk này, phạm vi của chỉ thị là đúng bị phá hủy và không có đối tượng bị rò rỉ. Rất đáng ngạc nhiên, thực sự. Nhưng tôi không sử dụng cùng một chế độ xem làm tổ mà tôi có trong phần đầu tiên; Tuy nhiên tôi nghi ngờ đó là nó. Phạm vi bộ điều khiển vẫn bị xóa khi chế độ xem thay đổi. Tôi vẫn có một người quan sát trên một vật thể bên trong. Vì vậy, tôi nghĩ tôi sẽ thấy một động lực tương tự. Nhưng có vẻ như việc phá hủy $ thực sự được gọi là phạm vi nội bộ đó.

Bất kỳ ý tưởng nào về điều gì sẽ ngăn cản phạm vi chỉ thị nhận được $ destroy() được gọi trên đó? CNTT dường như liên quan đến phạm vi: bit thực sự, nhưng tôi không thể khá grok góc nội bộ đủ để nói lý do tại sao.

Cảm ơn bạn trước,

Jesse


Cập nhật: OK, tôi sẽ đăng một bản cập nhật để vấn đề này.

Với khả năng tốt nhất của tôi, có vẻ như những gì đang xảy ra là phạm vi chính cho phần tử (không phải là phạm vi bán cô lập cho chỉ thị lưới) được $ destroy() d. Tuy nhiên, phạm vi con mà đang sử dụng phạm vi đó như nguyên mẫu có khả năng nhất định bailing ra khỏi phương pháp phá hủy $ sớm, bởi vì self. $$ bị phá hủy là true (prototypal inheritance). Vì vậy, người nghe và người xem không bị xóa.

Tôi có thể cập nhật chỉ thị được cô lập hoàn toàn trong phạm vi, nhưng tôi không có thời gian để phân loại các tác động của điều đó.

Tôi cũng nhận thấy nó không chỉ là phá hủy $. Bản thân $ scope có rất nhiều hàm được định nghĩa trên nó bởi chỉ thị rằng việc đóng biểu mẫu xung quanh các vars nội bộ chứa rất nhiều bộ nhớ.

Vì vậy, tôi đã viết một dịch vụ cung cấp thêm dọn dẹp dễ dàng được đưa vào chỉ thị lưới có vấn đề. Tôi có một bản demo lớn, nhưng tôi không thể đăng nó trong phần chính do danh tiếng thấp của tôi :). Bây giờ, bạn có thể chuyển đổi lưới tất cả các bạn thích và không có nhưng lưới hiện tại sẽ vẫn còn trên đống.

Hy vọng điều này sẽ giúp người đi về phía trước,

J

+1

Đây là liên kết đến các đoạn khác thể hiện độ phân giải được đề cập ở trên. http://plnkr.co/edit/r2uTKTJW2yJTbHx0kXYB – jessewolfe

+0

Xin chào, tôi có một vấn đề mà tôi nghĩ là có liên quan, bạn có thấy lý do tại sao $ phá hủy không được gọi trên phạm vi không? http://stackoverflow.com/questions/27467210/angular-directive-memory-leaks – Barnash

+0

Có thể thú vị: Bài viết này nói về những sự phá vỡ có thể xảy ra trong chuỗi phá hủy $ do các cây con xấu của các phạm vi phụ (cụ thể là: sử dụng jquery) http: //www.bennadel.com/blog/2706-always-trigger-the-destroy-event-before-removing-elements-in-angularjs-directives.htm – Offirmo

Trả lời

1

Không biết nếu điều này là phù hợp hơn như một lời nhận xét hay không. Gần đây tôi đã làm việc trên một dự án lớn sử dụng ng lưới + angularjs và chúng tôi đã có tất cả các vấn đề mà bạn đã gặp phải: rò rỉ bộ nhớ gallore. Chúng tôi thấy rằng thực sự không phải tất cả mọi thứ đã được làm sạch độc đáo và phạm vi và đồng hồ đã bị rò rỉ khắp nơi.

Chúng tôi đã cố gắng thêm một số logic tùy chỉnh để thử và thực hiện dọn dẹp tốt hơn nhưng nó không giải quyết được vấn đề của chúng tôi 100%. Vấn đề của chúng tôi cũng được nhấn mạnh bởi cuộn ngang + ảo hóa trên ng-lưới vì vậy nó có thể hữu ích để giữ cho rằng trong tâm trí là tốt (nếu tôi nhớ chính xác họ đã có kế hoạch sửa chữa này trong một phiên bản trong tương lai).

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