Hướng dẫn what is stored in heap in javascript? - những gì được lưu trữ trong đống trong javascript?
Show
Hầu hết thời gian, có lẽ bạn có thể nhận được bằng cách không biết gì về quản lý bộ nhớ với tư cách là nhà phát triển JavaScript. Sau tất cả, động cơ JavaScript xử lý việc này cho bạn. Tuy nhiên, tại thời điểm này hay lúc khác, bạn sẽ gặp phải vấn đề, như rò rỉ bộ nhớ, mà bạn chỉ có thể giải quyết nếu bạn biết cách thức phân bổ bộ nhớ hoạt động. Trong bài viết này, tôi sẽ giới thiệu cho bạn cách phân bổ bộ nhớ và thu gom rác hoạt động và cách bạn có thể tránh rò rỉ bộ nhớ thông thường.memory allocation and garbage collection works and how you can avoid some common memory leaks.
Vòng đời nhớBộ nhớ đống và ngăn xếp Stack: Phân bổ bộ nhớ tĩnh is the process of reserving space in memory, while releasing memory frees up space, ready to be used for another purpose. HEAP: Phân bổ bộ nhớ động
Bộ nhớ đống và ngăn xếpStack: Phân bổ bộ nhớ tĩnh HEAP: Phân bổ bộ nhớ động Ví dụmemory heap and stack. Tài liệu tham khảo trong JavaScript Stack: Phân bổ bộ nhớ tĩnh
Ví dụ Tài liệu tham khảo trong JavaScriptprimitive values (strings, numbers, booleans, undefined, and null) and references, which point to objects and functions. Thu gom rác thảifixed amount of memory for each value. Bộ sưu tập rác tham chiếustatic memory allocation. Thuật toán đánh dấu và quétlimit to how large primitive values can be. Rò rỉ bộ nhớvary depending on the browser. HEAP: Phân bổ bộ nhớ độngVí dụobjects and functions. Tài liệu tham khảo trong JavaScriptdoesn't allocate a fixed amount of memory for these objects. Instead, more space will be allocated as needed. Thu gom rác thảidynamic memory allocation. Bộ sưu tập rác tham chiếu
Ví dụTài liệu tham khảo trong JavaScript
Thu gom rác thải Bộ sưu tập rác tham chiếu Thuật toán đánh dấu và quét
Rò rỉ bộ nhớ Tài liệu tham khảo trong JavaScriptTất cả các biến đầu tiên chỉ vào ngăn xếp. Trong trường hợp đó là một giá trị không nguyên thủy, ngăn xếp chứa một tham chiếu đến đối tượng trong đống. Bộ nhớ của đống không được đặt hàng theo bất kỳ cách cụ thể nào, đó là lý do tại sao chúng ta cần giữ một tham chiếu đến nó trong ngăn xếp. Bạn có thể nghĩ về các tài liệu tham khảo dưới dạng địa chỉ và các đối tượng trong đống như những ngôi nhà mà các địa chỉ này thuộc về.
Trong bức tranh này, chúng ta có thể quan sát các giá trị khác nhau được lưu trữ như thế nào. Lưu ý cách 1 và 2 cả hai đều chỉ vào cùng một đối tượng.Ví dụ
Điều này tạo ra một đối tượng mới trong đống và tham chiếu đến nó trong ngăn xếp.
Thu gom rác thảiBây giờ chúng ta biết cách JavaScript phân bổ bộ nhớ cho tất cả các loại đối tượng, nhưng nếu chúng ta nhớ vòng đời bộ nhớ, thì có một bước cuối cùng bị thiếu: phát hành bộ nhớ. Cũng giống như phân bổ bộ nhớ, động cơ JavaScript cũng xử lý bước này cho chúng tôi. Cụ thể hơn, người thu gom rác chăm sóc điều này.garbage collector takes care of this. Khi công cụ JavaScript nhận ra rằng một biến hoặc hàm đã cho không cần thiết nữa, nó sẽ giải phóng bộ nhớ mà nó chiếm. Vấn đề chính với điều này là liệu một số bộ nhớ có cần thiết hay không là một vấn đề không thể giải quyết được, điều đó có nghĩa là không thể có một thuật toán có thể thu thập tất cả bộ nhớ không cần thiết nữa trong thời điểm chính xác nó trở nên lỗi thời.undecidable problem, which means that there can't be an algorithm that's able to collect all the memory that's not needed anymore in the exact moment it becomes obsolete. Một số thuật toán cung cấp một xấp xỉ tốt cho vấn đề. Tôi sẽ thảo luận về những cái được sử dụng nhiều nhất trong phần này: Bộ sưu tập rác đếm tham chiếu và thuật toán nhãn hiệu và quét. Bộ sưu tập rác tham chiếuĐây là xấp xỉ dễ nhất. Nó thu thập các đối tượng không có tài liệu tham khảo chỉ vào chúng.no references pointing to them. Chúng ta hãy xem ví dụ sau. Các dòng đại diện cho tài liệu tham khảo. Lưu ý làm thế nào trong khung cuối cùng chỉ 3 ở trong đống vì đó là đối tượng có tham chiếu cuối cùng.Chu kỳVấn đề với thuật toán này là nó không xem xét các tài liệu tham khảo theo chu kỳ. Điều này xảy ra khi một hoặc nhiều đối tượng tham chiếu lẫn nhau, nhưng chúng không thể được truy cập thông qua mã nữa.
Vì các đối tượng 4 và 5 tham chiếu lẫn nhau, thuật toán sẽ không giải phóng bộ nhớ được phân bổ. Không có cách nào để chúng tôi truy cập hai đối tượng nữa.Đặt chúng thành 6 sẽ không làm cho thuật toán đếm tham chiếu nhận ra rằng chúng không thể được sử dụng nữa vì cả hai đều có tài liệu tham khảo đến.Thuật toán đánh dấu và quétThuật toán đánh dấu và quét có một giải pháp cho các phụ thuộc theo chu kỳ. Thay vì chỉ cần đếm các tham chiếu đến một đối tượng nhất định, nó sẽ phát hiện nếu chúng có thể truy cập từ đối tượng gốc.reachable from the root object. Root trong trình duyệt là đối tượng 7, trong khi ở NodeJS thì đây là 8.
Thuật toán đánh dấu các đối tượng không thể truy cập được là rác và quét (thu thập) sau đó. Đối tượng gốc sẽ không bao giờ được thu thập.marks the objects that aren't reachable as garbage, and sweeps (collects) them afterward. Root objects will never be collected. Bằng cách này, phụ thuộc theo chu kỳ không còn là vấn đề nữa. Trong ví dụ từ trước, cả 5 và đối tượng 4 đều không đạt được từ gốc. Do đó, cả hai sẽ được đánh dấu là rác và thu thập.Kể từ năm 2012, thuật toán này được thực hiện trong tất cả các trình duyệt hiện đại. Những cải tiến chỉ được thực hiện để thực hiện và thực hiện, nhưng không phải là ý tưởng cốt lõi của thuật toán.implemented in all modern browsers. Improvements have only been made to performance and implementation, but not to the algorithm's core idea itself. Trade-offsThu thập rác tự động cho phép chúng tôi tập trung vào việc xây dựng các ứng dụng thay vì mất thời gian với quản lý bộ nhớ. Tuy nhiên, có một số sự đánh đổi mà chúng ta cần phải biết. Sử dụng bộ nhớCho rằng các thuật toán không thể biết khi nào chính xác bộ nhớ sẽ không cần thiết nữa, các ứng dụng JavaScript có thể sử dụng nhiều bộ nhớ hơn chúng thực sự cần.JavaScript applications may use more memory than they actually need. Mặc dù các đối tượng được đánh dấu là rác, nhưng tùy thuộc vào người thu gom rác để quyết định khi nào và nếu bộ nhớ được phân bổ sẽ được thu thập. Nếu bạn cần ứng dụng của mình là hiệu quả bộ nhớ nhất có thể, bạn nên tắt với ngôn ngữ cấp thấp hơn. Nhưng hãy nhớ rằng điều này đi kèm với bộ đánh đổi của riêng mình. Màn biểu diễnCác thuật toán thu thập rác cho chúng ta thường chạy định kỳ để làm sạch các vật không sử dụng. Vấn đề với điều này là chúng tôi, các nhà phát triển, không biết chính xác điều này sẽ xảy ra khi nào. Thu thập rất nhiều rác hoặc thu gom rác thường xuyên có thể ảnh hưởng đến hiệu suất vì nó cần một lượng sức mạnh tính toán nhất định để làm điều đó. Tuy nhiên, tác động thường không được chú ý đối với người dùng hoặc nhà phát triển. Rò rỉ bộ nhớĐược trang bị tất cả kiến thức này về quản lý bộ nhớ, hãy xem xét các rò rỉ bộ nhớ phổ biến nhất. Bạn sẽ thấy rằng những điều này có thể dễ dàng tránh được nếu một người hiểu những gì đang diễn ra đằng sau hậu trường. Biến toàn cầuLưu trữ dữ liệu trong các biến toàn cầu có lẽ là loại rò rỉ bộ nhớ phổ biến nhất. Chẳng hạn, trong trình duyệt, nếu bạn sử dụng 1 thay vì 2 hoặc ________ 23 hoặc bỏ hoàn toàn từ khóa, động cơ sẽ gắn biến vào đối tượng 7.Điều tương tự sẽ xảy ra với các chức năng được xác định với từ khóa 5.
Tất cả ba biến, 6, 7 và 8, sẽ được gắn vào đối tượng 7.Điều này chỉ áp dụng cho các biến và chức năng được xác định trong phạm vi toàn cầu. Nếu bạn muốn tìm hiểu thêm về điều này, hãy xem bài viết này giải thích phạm vi JavaScript. Tránh điều này bằng cách chạy mã của bạn ở chế độ nghiêm ngặt.strict mode. Ngoài việc vô tình thêm các biến vào gốc, còn có nhiều trường hợp bạn có thể làm điều này trên mục đích. Bạn chắc chắn có thể sử dụng các biến toàn cầu, nhưng hãy chắc chắn rằng bạn không có chỗ trống khi bạn không cần dữ liệu nữa. Để phát hành bộ nhớ, gán biến toàn cầu cho 6.
Những người hẹn giờ và gọi lạiQuên về bộ hẹn giờ và gọi lại có thể làm cho việc sử dụng bộ nhớ của ứng dụng của bạn tăng lên. Đặc biệt là trong các ứng dụng trang (SPA), bạn phải cẩn thận khi thêm người nghe sự kiện và gọi lại một cách linh hoạt. Những người hẹn giờ quên
Mã trên chạy chức năng cứ sau 2 giây. Nếu bạn có mã như thế này trong dự án của mình, bạn có thể không cần điều này để chạy mọi lúc. Các đối tượng được tham chiếu trong khoảng thời gian sẽ không được thu thập rác miễn là khoảng thời gian không bị hủy. Hãy chắc chắn để xóa khoảng thời gian một khi nó không cần thiết nữa.
Điều này đặc biệt quan trọng trong spa. Ngay cả khi điều hướng ra khỏi trang nơi cần khoảng, nó vẫn sẽ chạy ở chế độ nền. Quên gọi lạiGiả sử bạn thêm một trình nghe 1 vào một nút, sau này bị xóa.Các trình duyệt cũ không thể thu thập người nghe, nhưng ngày nay, đây không còn là vấn đề nữa.this isn't a problem anymore. Tuy nhiên, bạn nên loại bỏ người nghe sự kiện một khi bạn không cần họ nữa:
Không tham khảo DOMRò rỉ bộ nhớ này tương tự như các lần trước: nó xảy ra khi lưu trữ các thành phần DOM trong JavaScript.
Khi bạn loại bỏ bất kỳ phần tử nào trong số đó, có lẽ bạn cũng sẽ muốn loại bỏ phần tử này khỏi mảng. Nếu không, các yếu tố DOM này không thể được thu thập. 0Loại bỏ phần tử khỏi mảng giữ nó đồng bộ với DOM. Vì mọi yếu tố DOM cũng giữ một tham chiếu đến nút cha mẹ của nó, bạn sẽ ngăn người thu gom rác thu thập cha mẹ và con cái.you'll prevent the garbage collector from collecting the element's parent and children. Sự kết luậnTrong bài viết này, tôi đã tóm tắt các khái niệm cốt lõi về quản lý bộ nhớ trong JavaScript. Viết bài viết này đã giúp tôi làm rõ một số khái niệm mà tôi không hiểu hoàn toàn và tôi hy vọng điều này sẽ đóng vai trò là một cái nhìn tổng quan tốt về cách quản lý bộ nhớ hoạt động trong JavaScript. Tôi đã học được điều này từ một số bài báo tuyệt vời khác mà tôi cũng muốn đề cập ở đây:
Các bài viết khác mà bạn có thể quan tâm:
Nếu bạn muốn có thêm các bài viết như thế này, hãy để lại cho tôi một tin nhắn và đảm bảo rằng bạn đã đăng ký nhận bản tin email của tôi. Dữ liệu nào được lưu trữ trong đống?HEAP là một bộ nhớ được sử dụng bởi các ngôn ngữ lập trình để lưu trữ các biến toàn cầu. Theo mặc định, tất cả các biến toàn cầu được lưu trữ trong không gian bộ nhớ heap. Nó hỗ trợ phân bổ bộ nhớ động.global variables. By default, all global variable are stored in heap memory space. It supports Dynamic memory allocation.
Những gì được lưu trữ trong khu vực đống?Bất cứ khi nào một đối tượng được tạo, nó luôn được lưu trữ trong không gian heap và bộ nhớ ngăn xếp chứa tham chiếu đến nó. Bộ nhớ ngăn xếp chỉ chứa các biến nguyên thủy cục bộ và các biến tham chiếu đến các đối tượng trong không gian đống., it's always stored in the Heap space and stack memory contains the reference to it. Stack memory only contains local primitive variables and reference variables to objects in heap space.
Những gì được lưu trữ trong đống của một quá trình?HEAP là một khu vực của bộ nhớ, giống như ngăn xếp, lưu trữ các biến trong một chương trình đang chạy.Không giống như ngăn xếp, bộ nhớ trong đống không được gắn với một chức năng cụ thể.Điều đó có nghĩa là một hàm có thể phân bổ bộ nhớ trên đống và các chức năng khác có thể sử dụng bộ nhớ đó một cách an toàn cho đến khi nó không còn cần thiết.variables in a running program. Unlike the stack, memory in the heap isn't tied to a specific function. That means one function can allocate memory on the heap, and other functions can safely use that memory until it's no longer needed.
Một đống chứa bao nhiêu?HEAP chứa một danh sách liên kết các khối được sử dụng và miễn phí.Phân bổ mới trên đống (bởi mới hoặc malloc) được thỏa mãn bằng cách tạo một khối phù hợp từ một trong các khối miễn phí.a linked list of used and free blocks. New allocations on the heap (by new or malloc ) are satisfied by creating a suitable block from one of the free blocks.
JavaScript có sử dụng đống và ngăn xếp không?Lưu trữ bộ nhớ trong JavaScript # Vì JavaScript thường chỉ được ren đơn, thường có một ngăn xếp.Ngăn xếp cũng có kích thước giới hạn, đó là lý do tại sao các số trong JavaScript chỉ có thể lớn như vậy.Các heap, là một cửa hàng bộ nhớ động ở cấp độ ứng dụng. |