5

Tôi có câu hỏi về bộ sưu tập rác/bộ nhớ rò rỉ Javascript. Tôi đang sử dụng Chrome 28.0.1500.71 trên OS X 10.8.4.Rò rỉ bộ nhớ JavaScript đóng cửa

Mã sau không bao giờ giải phóng không gian được giữ bởi me và tôi không biết gì về lý do.

var MyClass = function() { 
    this.x = 1; 

    var self = this; 
    this.do_thing = function() { 
     self.x++; 
    }; 
}; 
MyClass.prototype.destroy = function() { 
    delete this.do_thing; 
}; 

var me = new MyClass(); 
me.do_thing(); 
me.destroy(); 
me = null; 

// the MyClass object formerly known as 'me' is still allocated here 
// (as evidenced by Chrome's heap profiler) 

Chrome dường như để giữ cho các đối tượng được tạo ra bởi sự biểu hiện new MyClass() (đối tượng mà me chỉ vào trước khi được thiết lập để null) trong bộ nhớ bởi vì nó được tham chiếu bởi self trong cuộc gọi đến me.do_thing(). Tuy nhiên, tôi đã có thể nghĩ rằng cuộc gọi đến destroy(), trong đó unets me.do_thing sẽ vứt bỏ các biến trong phạm vi của các nhà xây dựng (self trong các cuộc gọi new MyClass()).

Tôi cũng đã thử sử dụng chức năng _.bind của Underscore.JS nhưng chạy vào cùng một vấn đề chưa được giải quyết được mô tả tại đây: Instances referenced by 'bound_this' only are not garbage collected.

+0

Hãy chính xác và phân biệt giữa "biến toàn cầu' me' "và" đối tượng MyClass' ". Biến chắc chắn sẽ vẫn còn trong bộ nhớ, nhưng đó không phải là một vấn đề (và nếu có, bạn có thể loại bỏ nó khỏi 'cửa sổ', xem câu trả lời của simonleung). Chrome có cho biết đối tượng 'MyClass' vẫn còn sống không? – delnan

+0

Điểm công bằng; đó là đối tượng 'MyClass' * được * tham chiếu bởi' me' mà không bao giờ bị deallocated. Tôi đã cập nhật từ ngữ của câu hỏi của mình để làm cho điều này rõ ràng hơn. – soney

+1

Có vẻ như có lỗi trong V8, tôi đã mở một vấn đề với điều này: https://code.google.com/p/v8/issues/detail?id=2791 –

Trả lời

0

tôi vẫn là thuộc tính của đối tượng cửa sổ ngay cả khi bạn đặt thành giá trị rỗng. Vì vậy, "tôi" vẫn còn trong bộ nhớ.

Tôi nghĩ rằng đây có thể giúp:

window.me = new MyClass(); 
me.do_thing(); 
delete window.me; 
+0

Đoạn mã này vẫn để nguyên đối tượng 'MyClass' được phân bổ trong trình duyệt của tôi. – soney

1

Tôi không biết lý do tại sao nó không phải là thu gom rác thải, nhưng thêm các phương pháp phá hủy đến dụ thay vì nguyên mẫu và thiết self null, rõ ràng sẽ làm việc :

var MyClass = function() { 
    this.x = 1; 

    var self = this; 
    this.do_thing = function() { 
     self.x++; 
    }; 

    this.destroy = function() { 
     delete this.do_thing; 
     self = null; 
    }; 
}; 

var me = new MyClass(); 
me.do_thing(); 
me.destroy(); 
me = null; 
+0

Thú vị, mặc dù tôi vẫn tò mò tại sao 'self' cần phải được xử lý thủ công là – soney

+0

@ tiền, có vẻ như nó có liên quan đến việc gán' self.x' trong dòng 'self.x ++'. Nếu bạn thay đổi dòng đó thành 'return self.x', nó cũng sẽ bị thu gom rác. – basilikum

0

MyClass là biến toàn cục. Nó cũng là một thuộc tính của đối tượng cửa sổ trong môi trường trình duyệt. Nó không phải là một thùng rác vì couse nó sẽ không được thu thập.

+0

Trong khi chức năng 'MyClass' đang chiếm dung lượng, tôi đang đề cập đến đối tượng được tạo bởi biểu thức' new MyClass() '. Sau khi 'me' được đặt thành null, nó sẽ không có bất kỳ tham chiếu nào khác và cần được thu thập. – soney

+0

đối tượng sẽ được thu thập bởi gc, không phải ngay lập tức. Hãy thử làm mới và genrate một heap snapshot mới, bạn sẽ không thấy bất kỳ đối tượng MyClass nào. – simonleung

0

Trông giống như một lỗi. Btw me.destroy() là không cần thiết. Nó sẽ bị xóa mà không có nó.