Computer >> Máy Tính >  >> Lập trình >> Javascript

Giải thích chi tiết về rò rỉ bộ nhớ trong JavaScript?

Rò rỉ bộ nhớ trong JavaScript

JavaScript được gọi là ngôn ngữ thu gom rác, tức là khi các biến được khai báo, nó sẽ tự động cấp phát bộ nhớ cho chúng. Khi không còn tham chiếu nào nữa cho các biến đã khai báo, bộ nhớ được cấp phát sẽ được giải phóng. Rò rỉ bộ nhớ hoặc hầu hết các sự cố liên quan đến bộ nhớ sẽ xảy ra khi giải phóng bộ nhớ.

Một số rò rỉ JavaScript phổ biến

1) Các biến tổng thể tình cờ

Khi một biến chưa khai báo được tham chiếu, javascript sẽ tạo một biến mới trong đối tượng toàn cục. Trong Ví dụ-1 sau đây, giả sử mục đích của các ngôn ngữ là chỉ tham chiếu đến một biến trong hàm "myArray". Nếu chúng ta không sử dụng var để khai báo thì một biến toàn cục sẽ được tạo. Nó có thể không gây hại nhiều, nhưng vấn đề chính phát sinh khi vô tình một biến toàn cục được tạo bằng cách sử dụng từ khóa "this" như được hiển thị trong Ví dụ-2.

Ví dụ-1

function myArray(arg) {
   languages = "[javascript,.....]";  //  created using window
}

Ví dụ-2

function myArray(arg) {
   this.languages = "[javascript,.....]";  // global object  
}

vì phạm vi của các biến toàn cục không bao giờ kết thúc, chúng vẫn còn trong bộ nhớ trong suốt quá trình thực thi trang ngay cả khi chúng không cần thiết. đối tượng còn lại trong bộ nhớ). Càng nhiều biến toàn cục, bộ nhớ càng rò rỉ.

2) Đóng cửa

Bao đóng là một hàm bên trong có thể truy cập vào các biến (phạm vi) của hàm bên ngoài. Ngoài ra, hàm bên trong sẽ tiếp tục có quyền truy cập vào phạm vi của hàm bên ngoài ngay cả sau khi hàm bên ngoài được thực hiện. hàm lồng nhau bên trong.

Trong ví dụ dưới đây, vì tất cả các hàm bên trong trong một bao đóng đều có chung ngữ cảnh, nên innFun () chia sẻ cùng ngữ cảnh với "function () {}" được trả về bởi hàm ngoài. Bây giờ, cứ sau 3ms, chúng ta thực hiện một cuộc gọi hàm đến outFun, một giá trị mới (sau mỗi lần gọi) được gán cho một giá trị mới của biến toàn cục. Miễn là tham chiếu trỏ đến "function () {}" này, phạm vi dùng chung sẽ được duy trì và mảng được giữ lại vì nó là một phần của hàm bên trong (innFun) ngay cả khi hàm bên trong không bao giờ được gọi. Mỗi lần chúng ta gọi hàm ngoài (outFun), chúng ta lưu hàm trước đó () {} trong giá trị (biến) của hàm mới. Do đó, một lần nữa, phạm vi được chia sẻ trước đó phải được giữ lại. Vì vậy, trong lần gọi thứ n của hàm bên ngoài (outFun), mảng của lệnh gọi thứ (n-1) của hàm bên ngoài không thể được thu gom. Quá trình này sẽ dừng lại khi bộ nhớ hết cuối cùng.

Ví dụ

var newvalue;
function outFun() {
   var array = new Array(1000000);
   var value = newvalue;
      function innFun() {
        if (value) return array;
   }
   return function () {};
}
setInterval(function () {
   newvalue = outFun();
   }, 3);