Rò rỉ bộ nhớ xảy ra khi bộ nhớ không còn cần thiết bởi chương trình nhưng lại không được giải phóng. Trong JavaScript, bộ nhớ được quản lý tự động bởi bộ thu gom rác (garbage collector), nó sẽ loại bỏ các đối tượng không còn khả năng truy cập. Tuy nhiên, có một số tình huống ngăn cản bộ thu gom rác nhận ra các đối tượng không cần dùng nữa, gây ra sự tích tụ bộ nhớ không cần thiết.
Nguyên nhân của rò rỉ bộ nhớ:
var
, let
hoặc const
sẽ trở thành biến toàn cục và tồn tại trong bộ nhớ cho đến khi phiên duyệt web kết thúc.setInterval
hoặc setTimeout
mà không xóa chúng có thể gây tích tụ bộ nhớ, đặc biệt khi hàm liên kết tham chiếu đến các đối tượng không còn cần thiết.Ví dụ về rò rỉ bộ nhớ:
globalArray
Trong ví dụ này, objA
và objB
tham chiếu lẫn nhau, ngăn bộ thu gom rác giải phóng chúng. Để khắc phục, hãy thiết lập objA.ref
hoặc objB.ref
thành null
khi không còn cần thiết.
Closures là một tính năng quan trọng của JavaScript, cho phép các hàm bên trong truy cập các biến trong hàm bên ngoài. Tuy nhiên, closures có thể gây ra rò rỉ bộ nhớ nếu không được quản lý đúng cách, vì chúng giữ lại tham chiếu đến các biến trong phạm vi của hàm bên ngoài.
Cách closures gây ra rò rỉ bộ nhớ: Khi một hàm có closure được trả về hoặc truyền đi, nó có thể giữ lại các biến không cần thiết. Nếu closure giữ lại tham chiếu đến một đối tượng lớn, đối tượng đó sẽ còn tồn tại trong bộ nhớ một cách không cần thiết.
Ví dụ về closure gây ra rò rỉ bộ nhớ:
largeObject
Event listeners rất phổ biến trong JavaScript, và việc quản lý chúng không đúng cách có thể dễ dàng gây ra rò rỉ bộ nhớ. Điều này xảy ra khi các event listeners được gắn vào các phần tử DOM sau đó bị xóa khỏi DOM nhưng vẫn được tham chiếu trong JavaScript.
Cách event listeners gây ra rò rỉ bộ nhớ: Event listeners giữ lại tham chiếu đến các phần tử mà chúng được gắn vào. Khi phần tử đó bị xóa khỏi DOM nhưng event listener không bị gỡ bỏ, phần tử đó vẫn còn tồn tại trong bộ nhớ, ngăn bộ thu gom rác giải phóng nó.
Ví dụ về rò rỉ bộ nhớ do event listener:
removeEventListener
Timers và intervals cũng có thể dẫn đến rò rỉ bộ nhớ nếu không được quản lý đúng cách. Các hàm được truyền vào setInterval
hoặc setTimeout
có thể giữ tham chiếu đến các đối tượng hoặc phần tử DOM lớn, khiến chúng tồn tại trong bộ nhớ lâu hơn cần thiết.
Ví dụ về Timer gây ra rò rỉ bộ nhớ:
largeObject
Bằng cách áp dụng những kỹ thuật này, bạn có thể tránh được rò rỉ bộ nhớ trong JavaScript và đảm bảo ứng dụng của mình hoạt động hiệu quả.