THÔNG DỤNG
OOP
ES6
ES(X)
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Rò rỉ bộ nhớ RAM và CPU khi làm việc với Javascript

Javascript rất hay nhưng việc lạm dụng nó hoặc code không tối ưu thì rất nguy hiểm bởi vì việc tràn bộ nhớ RAM là có thể xảy ra. nên nếu bạn đang lập trình cho một website và khi chạy thì thấy bị rò rỉ bộ nhớ một cách nghiêm trọng thì rất có thể là do ứng dụng của bạn gây ra.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Bài viết dưới đây sẽ tham khảo bài của ông Volkan, trước đây ông điều hành trang sarmal.com (giờ site đã chết), ông đã viết ra bài này trong quá trình điều hành và sử dụng website của mình.

1. Tại sao lại rò rỉ bộ nhớ?

Vấn đề rò rỉ bộ nhớ không chỉ xuất hiện ở Internet Explorer mà mọi browser như Chrome, Firefox, Netscape, Opera đều xảy ra hiện tượng này, tuy nhiên theo bản thân ông thì IE là ông vua của hiện tượng này.

Không phải chỉ mỗi ông ghét IE mà hầu như mọi lập trình viên trên thế giới đều ghét IE, không phải vì ganh tị mà về tính năng, giao diện của IE rất hạn chế, kém cỏi hơn rất nhiều so với các trình duyệt khác. ở Việt Nam thì sử dụng thông dụng nhất vẫn là Chrome, Firefox và Cốc Cốc (một sản phẩm của VN).

Bài viết này được đăng tại [free tuts .net]

Mỗi trình duyệt đều có một ưu điểm và nhược điểm riêng. Chẳng hạn như Firefox thì tốn rất nhiều RAM cho việc khởi động, nó không tốt cho việc xử lý chuỗi và mảng, còn Opera thì có thể sẽ bị chết nếu bạn viết một tập lệnh DHTML phức tạp đến mức gây nhầm lẫn cho công cụ convert của nó.

Và trong bài viết này ông Volkan sẽ tập trung vào việc phân tích sự rò rỉ bộ nhớ trên trình duyệt IE, và có thể áp dụng vào các trình duyệt khác.

2. Ví dụ rò rỉ bộ nhớ đơn giản

Hãy bắt đầu bằng một ví dụ đơn giản dưới đây, lý do ta insert một đoạn code JS inline.

<html>
<head>
<script type="text/javascript">
    function LeakMemory(){
        var parentDiv = 
             document.createElement("<div onclick='foo()'>");
 
        parentDiv.bigString = new Array(1000).join(
                              new Array(2000).join("XXXXX"));
    }
</script>
</head>
<body>
<input type="button"
       value="Memory Leaking Insert" onclick="LeakMemory()" />
</body>
</html>

Đầu tiên đoạn code parentDiv=document.createElement(...); sẽ tạo một thẻ div và nó sẽ hoạt động tạm thời trong phạm vi của script đó, tiếp theo parentDiv.bigString=... gắn một đối tượng có giá trị rất lớn vào thẻ div. Khi phương thức LeakMemory() được gọi thì một phần tử DOM sẽ khởi tạo, và gán giá trị rất lớn đó vào thẻ div, sau đó nó sẽ kết thúc mọi thứ vì đây là một hàm nên phạm vi hoạt động của các biến là cục bộ.

Khi bạn chạy thử và soi bộ nhớ thì sẽ thấy lúc chạy chương trình này thì RAM và CPU đã thực sự bị rò rỉ.

ro ri ram js 1 gif

3. Ví dụ rò rỉ phức tạp hơn

Nếu bạn cảm thấy việc đó là quá bình thường thì hãy thử chạy chương trình đó 10 lần, 100 lần và trải nghiệm xem thé nào? có thể máy tính của bạn sẽ đơ và buộc phải khởi động nguội đấy. Bây giờ ông Volkan đã tăng việc xử lý của hàm LeakMemory lên 5000 lần vào cùng một thời điểm để xem kết quả thế nào.

<html>
<head>
<script type="text/javascript">
    function LeakMemory(){
        for(i = 0; i < 5000; i++){
            var parentDiv = 
               document.createElement("<div onClick='foo()'>");
        }
    }
</script>
</head>
<body>
<input type="button"
       value="Memory Leaking Insert" onclick="LeakMemory()" />
</body>

Chạy chương trình này thì bạn sẽ thấy sơ đồ của RAM và CPU như sau:

ro ri ram js 2 gif

Nếu bạn thử chạy ứng dụng demo này ở nhiều tab khác nhau thì rất có thể bại sẽ phải khởi động lại trình duyệt, nặng hơn là khởi động lại máy tính, điều này gây phiền toái cho khách hàng khi sử dụng website rất nhiều.

Bây giờ ta thử sửa lại đoạn code đó với việc lặp 5000 lần nhưng chỉ khởi tạo thẻ div thôi, không gán dữ liệu quá lớn vào thì kết quả sẽ như thế nào?

<html>
<head>
<script type="text/javascript">
    function LeakMemory(){
        for(i = 0; i < 50000; i++){
            var parentDiv = 
            document.createElement("div");
        }
    }
</script>
</head>
<body>
<input type="button"
       value="Memory Leaking Insert" onclick="LeakMemory()" />
</body>
</html>

Và dưới đây là biểu đồ bộ nhớ.

ro ri ram js 3 gif

Như hình này thì bạn thấy việc rò rỉ bộ nhớ là khoong có, bởi vì sơ đồ hoạt động theo một đường thẳng, còn việc nó cao là do ông đã chạy một số ứng dụng khác => không có sự rò rỉ bộ nhớ trong trường hợp này.

Vậy, chúng ta hãy thay đổi code một cách đơn giản và hạn chết việc lạm dụng quá nhiều JS trên trang để tránh tình trạng tốn tài nguyên của khách hàng khi sử dụng website.

Cùng chuyên mục:

Functional Programming là gì? Tại sao và khi nào bạn nên sử dụng trong JavaScript

Functional Programming là gì? Tại sao và khi nào bạn nên sử dụng trong JavaScript

Những tính năng mới trong ES6+ trong JavaScript

Những tính năng mới trong ES6+ trong JavaScript

4 cách tránh memory leaks trong JavaScript

4 cách tránh memory leaks trong JavaScript

Capturing và bubbling Event trong Javascript

Capturing và bubbling Event trong Javascript

Phân biệt prototype và __proto__ trong JavaScript

Phân biệt prototype và __proto__ trong JavaScript

Cách hoạt động của Event Loop trong JavaScript

Cách hoạt động của Event Loop trong JavaScript

Phương thức bind(), call(), và apply() trong JavaScript

Phương thức bind(), call(), và apply() trong JavaScript

Cách khắc phục lỗi

Cách khắc phục lỗi "hoisting" trong JavaScript

Sử dụng Promise.all và Promise.race để quản lý các Promise trong JavaScript

Sử dụng Promise.all và Promise.race để quản lý các Promise trong JavaScript

Xử lý bất đồng bộ bằng vòng lặp for-await trong JavaScript

Xử lý bất đồng bộ bằng vòng lặp for-await trong JavaScript

Sự khác biệt giữa Promise, Callback và Async/Await trong JavaScript

Sự khác biệt giữa Promise, Callback và Async/Await trong JavaScript

Cách sử dụng Async functions trong JavaScript

Cách sử dụng Async functions trong JavaScript

Hàm String isspace() trong Python

Hàm String isspace() trong Python

Cách tạo số ngẫu nhiên trong Javascript

Cách tạo số ngẫu nhiên trong Javascript

Hướng dẫn cách tạo một số ngẫu nhiên ...

Cách gộp hai object javascript lại với nhau

Cách gộp hai object javascript lại với nhau

Cách lấy chiều dài của object trong Javascript

Cách lấy chiều dài của object trong Javascript

Hướng dẫn giải phương trình bậc 1 bằng Javascript

Hướng dẫn giải phương trình bậc 1 bằng Javascript

Cách dùng nextSibling trong javascript

Cách dùng nextSibling trong javascript

Cách dùng insertAdjacentHTML trong javascript

Cách dùng insertAdjacentHTML trong javascript

Cách dùng innerHTML trong Javascript

Cách dùng innerHTML trong Javascript

Top