2013-05-09 25 views
5

Khi chúng tôi bắt đầu thử nghiệm dự án NodeJS của chúng tôi, chúng tôi nhận thấy sự tham gia bộ nhớ lớn. Nó là do rò rỉ bộ nhớ trên tất cả các dự án của chúng tôi. Vì vậy, chúng tôi bắt đầu tìm kiếm tất cả các nguyên nhân có thể tạo ra rò rỉ bộ nhớ. Có một số câu trả lời cho câu hỏi đó trên stackoverflow, nhưng không có bất kỳ tài liệu chặt chẽ về những gì được và những gì không phải là một rò rỉ bộ nhớ.Rò rỉ bộ nhớ và sự cố đóng cửa trong NodeJS

Câu hỏi của tôi:

  • Có một tài liệu trên V8 GC và làm thế nào nó hoạt động (chi tiết)?
  • Cách phát hành cuộc gọi lại để GC có thể thu thập chúng?
  • Liệu V8 GC có thu thập các biến không được sử dụng nhưng có một chức năng đóng bên dưới chúng không? Ví dụ:

    var serviceChannel = require('./channel'); 
    var dataRegistration = require('../data/registration'); 
    
    function registerOnChannel(userID, channelID, callsuccess, callerror) { 
    
        serviceChannel.findChannel(channelID, function (channel) { 
         if (!channel) { 
          callerror("Channel doesn' exists"); 
          return; 
         } 
         dataRegistration.registerOnChannel(userID, channelID, function (registration) { 
          if (!registration) { 
           callerror("Registration doesn' exists"); 
           return; 
          } 
          callsuccess("Registration successful"); 
         }, function (error) { 
          callerror("Error on registration"); 
         }) 
        }, function (error) { 
         callerror("Error on finding channel"); 
        }) 
    } 
    

Vì vậy, serviceChannel và dataRegistration sẽ được giữ trong bộ nhớ càng lâu càng registerOnChanel là sống. Nhưng kênh biến sẽ bị xóa bởi GC (nó không được sử dụng bởi bất kỳ chức năng nào)?

+0

"Vì vậy, serviceChannel và dataRegistration sẽ được lưu trong bộ nhớ miễn là registerOnChanel đang hoạt động". Làm thế nào để bạn đi đến kết luận đó? –

+0

Đó là một đóng cửa. –

+0

Không có bằng chứng đóng cửa trong mã bạn đăng, ít nhất không phải như vậy mà sẽ giữ serviceChannel hoặc dataRegistration còn sống. –

Trả lời

0

Trước tiên, tôi muốn bạn chuyển API của mình để sử dụng được xây dựng trong EventEmitter (http://nodejs.org/api/events.html).

V8 V8 có thu thập các biến không được sử dụng nhưng có chức năng đóng bên dưới chúng không?

Nếu bạn sử dụng biến từ phạm vi chức năng trước đó thì biến sẽ phải nằm xung quanh cho đến khi phạm vi chức năng chứa và tất cả cuộc gọi có chứa biến đó, đã nằm ngoài phạm vi.

Nhưng kênh biến sẽ bị xóa bởi GC (nó không được sử dụng bởi bất kỳ chức năng nào)?

Dựa trên ví dụ mã bạn đã đăng, có nó sẽ được GC thu thập. Nhưng nó rất có thể đã bị rò rỉ một tham chiếu hoặc hai mà không nhận thấy.

+0

Tôi đã thử nghiệm NodeJS với một số biến thể của ví dụ này và GC luôn loại bỏ các đối tượng và các biến khi không có ai tham chiếu chúng. Tôi cũng nhận thấy rằng GC chỉ chạy nếu có nhu cầu (chế độ lười). Nếu chương trình tiêu thụ một số bộ nhớ, nó sẽ không được phát hành cho đến khi yêu cầu phân bổ bộ nhớ mới được thực hiện. V8 GC đang hoạt động rất tốt. –