THÔNG DỤNG
OOP
ES6
ES(X)
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
Dự án mới của mình là gamehow.net, mời anh em ghé thăm và góp ý ạ.

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.

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.

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.

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).

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:

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

Cách dùng insertBefore trong javascript

Cách dùng insertBefore trong javascript

Cách dùng insertAfter trong Javascript

Cách dùng insertAfter trong Javascript

Cách dùng parentNode trong Javascript

Cách dùng parentNode trong Javascript

Cách dùng parentElement trong Javascript

Cách dùng parentElement trong Javascript

Tính tổng các phần tử trong mảng javascript

Tính tổng các phần tử trong mảng javascript

Tính tổng hai số bằng Javascript (cộng hai số)

Tính tổng hai số bằng Javascript (cộng hai số)

Cách gán giá trị cho thẻ input trong javascript

Cách gán giá trị cho thẻ input trong javascript

Để gán giá trị cho thẻ input thì ta có hai cách, thứ nhất là…

Cách kiểm tra số nguyên âm trong javascript

Cách kiểm tra số nguyên âm trong javascript

Cách kiểm tra số nguyên dương trong javascript

Cách kiểm tra số nguyên dương trong javascript

Hàm closure trong javascript

Hàm closure trong javascript

Closure là một khái niệm không phải ai cũng ..

Biểu thức chính quy RegEx trong Javascript

Biểu thức chính quy RegEx trong Javascript

Bài này chúng ta sẽ tìm hiểu đến chuỗi và cách sử dụng biểu thức…

Cách dùng Import / Export Module trong javascript

Cách dùng Import / Export Module trong javascript

Khi bạn xây dựng một ứng dụng nhỏ thì việc đặt

Cơ chế hoạt động của hoisting trong Javascript

Cơ chế hoạt động của hoisting trong Javascript

Hoisting là vấn đề liên quan đến cách khai báo biến trong Javascript. Nó liên…

Cấp độ private / protected của class trong Javascript

Cấp độ private / protected của class trong Javascript

Top