2013-10-23 20 views
6

Giả sử tôi có một máy chủ http đơn giản như:Rò rỉ bộ nhớ khi sử dụng luồng trong Node.js?

var http = require('http'); 

http.createServer(function (req, res) { 
    req.on('data', function (data) { 
    console.log('Got some data: ' + data); 
    }); 

    req.on('end', function() { 
    console.log('Request ended!'); 
    }); 

    res.end('Hello world!'); 
}).listen(3000); 

Vì vậy, về cơ bản mặc định 101 mẫu, không có gì đặc biệt cho đến nay - ngoại trừ việc tôi đăng ký vào dataend sự kiện của thể đọc được req suối. Bây giờ tôi tự hỏi liệu tôi có phải hủy đăng ký những sự kiện đó khi tôi không còn cần chúng nữa không?

Hoặc chúng có được xóa tự động khi luồng có thể đọc được kết thúc không?

Có thể mã như thế này gây ra rò rỉ bộ nhớ không?

+3

[Điều này] (http://stackoverflow.com/questions/5326300/garbage-collection-with-node-js) có thể hữu ích. – hexacyanide

+0

Điều đó thực sự hữu ích theo nghĩa thông thường hơn. Cảm ơn :-) –

Trả lời

15

(Câu trả lời này có chứa các liên kết đến các phần Revelant của mã nguồn Node.js)

Trước khi trả lời câu hỏi của bạn, chúng ta hãy nói về các sự kiện. Khi bạn làm điều này:

emitter.on('an-event', listener); 

listener được thêm vào một list gắn liền với emitter. Sau đó, khi emitter kích hoạt sự kiện, nó sẽ thông báo cho tất cả người nghe đã đăng ký sự kiện bằng cách lặp qua danh sách. Sự kỳ diệu của bộ phát sự kiện node.js là bạn không tự khai báo hoặc tự quản lý danh sách đó.

Tuy nhiên, bất cứ khi nào bạn gọi .on(), bạn tạo một trình phát phát sóng back-reference ->. Tham chiếu này sẽ ngăn người nghe thu thập dữ liệu từ GC và tạo "rò rỉ" nếu bạn không bao giờ hủy đăng ký. Điều này không xảy ra thường xuyên với node.js, bởi vì thường, các bộ phát bị phá hủy trước người nghe, nhưng trường hợp thực tế xảy ra khi bạn có kết nối dài (nghĩ rằng Twitter Streaming API) đôi khi kết nối lại . Nếu bạn không hủy đăng ký sự kiện, bạn có thể nhận sự kiện từ kết nối cũ và nghĩ rằng họ đã đăng ký sự kiện mới. Điều này có thể khiến bạn nghĩ rằng kết nối mới đã đóng.

node.js sẽ in thông báo "possible leak detected" khét tiếng khi nghĩ rằng bạn có thể quên bỏ đăng ký người nghe.

Quay lại ví dụ của bạn:

Điều này sẽ không tạo rò rỉ vì ổ cắm (req + res) sẽ bị hủy trước. Vì nó là bộ phát, node.js sẽ forcibly remove all listeners.

+0

Câu trả lời tuyệt vời, cảm ơn rất nhiều, đặc biệt là đối với một phần khi phát ra bị phá hủy. :-) –