JS of memory leaks

Today, sharing knowledge memory leak under the JS with you.

1 JS of memory leaks

Introduction
When dealing with such a scripting language JavaScript, it is easy to forget that each of the objects, classes, strings, numbers and methods need to be allocated and reserved memory. Language and run-time garbage collector hides the details of memory allocation and release.
Many features can be realized without regard to memory management, but ignored it may cause great problems in the program. Improper cleaning up objects may exist much longer than expected. These objects continue to respond to events and consume resources.
They can force the browser to allocate memory pages from a virtual disk drive, which significantly affects the speed of the computer (in extreme cases, can cause the browser to crash).

A memory leak means that an object no longer has any need or later it's still there in your. In recent years, many browsers have the ability to improve the page loading process from JavaScript reclaim memory. However, not all browsers have the same mode of operation.

Older versions of Firefox and Internet Explorer have existed memory leaks and memory leaks continued until the browser is closed.

Over the past led to many classic mode memory leaks in modern browsers to no longer causes a memory leak. However, there is a different trend affects memory leaks now. Many are designed for Web applications that run in the absence of hard page refresh a single page. As a single page, the state of the application from one state to another, it is easy to retain no longer required or not associated memory.

In this article, learn basic life cycle of the object, the garbage collector on how to determine whether an object is released, and how to evaluate potential leakage behavior. In addition, learn how to use Heap Profiler Google Chrome is to diagnose memory problems. Some examples show how to solve the closures, and console log cycle caused a memory leak.

Object lifecycle
To learn how to prevent memory leaks, need to understand the basic life cycle of the object. When you create an object, JavaScript will automatically allocate the appropriate memory for the object. From this moment, the garbage collector will continue to evaluate the object to see if it is still valid object.

Garbage collector periodically scans the object, and calculates the number of references to other objects of each object. If an object reference number is 0 (no other object reference through the object), or the only reference to the object is circular, then the object's memory can be recovered.
Figure 1 shows an example of the garbage collector memory.
Figure 1. garbage collection to reclaim memory
Here Insert Picture Description
to see the practical application of the system would be helpful, but this feature provides the tool is limited. Know your JavaScript application consumes how much memory is a way to use the system tools to see the browser's memory allocation. There are several tools available for your current usage, and memory usage trends depict a process of change over time.

For example, if you installed XCode on Mac OSX, you can start the Instruments application and its activity monitor tool attached to your browser for real-time analysis. On Windows®, you can use the Task Manager. If in the process you use an application, we found the memory usage versus time curve rose steadily, then you know there is a memory leak.

Observation browser's memory footprint only the crudest indicator of actual memory usage of JavaScript applications. Browser data will not tell you which objects a leak, can not guarantee real memory usage data with your application does match.

Moreover, due to the release of some of the problems to achieve browser, DOM elements (or backup application-level objects) may not destroy the corresponding element in the page. This is especially true video tag, video tag you need to implement a more sophisticated infrastructure.

It has repeatedly tried to add tracking to memory allocation on the client-side JavaScript library. Unfortunately, all attempts are not particularly reliable.

For example, the popular stats.js package inaccuracies can not be supported. In general, try to maintain or from the client determines that there is a certain problem with this information, because it introduces overhead in the application and can not be reliably terminated.

The ideal solution is a browser vendor in the browser a set of tools to help you monitor memory usage, identify objects leakage, and determine why a particular object is still marked as reserved.

Currently, only Google Chrome (provided Heap Profile) implements a memory management tool as its developer tools. I use HeapProfiler testing and demonstration JavaScript in this article how to handle run-time memory.

Analysis heap snapshots
before creating a memory leak, please check the appropriate time to collect simple interaction memory. First, create a simple HTML page that contains two buttons, as shown in Listing 1.
Listing 1. index.html
Here Insert Picture Description
include jQuery in order to ensure a simple syntax for managing event bindings for different browsers, and strict compliance with the most common development practices. Add a script tag for the leaker classes and major JavaScript methods. In a development environment, will merge JavaScript files into a single file is usually a better approach. For purposes of this example, the logic in a separate file easier.

You can filter Heap Profiler instance of a particular class to display only. To take advantage of this feature, create a package leaking objects to the behavior of the new class, and this class is very easy to find in Heap Profiler, as shown in Listing 2.
Listing 2.assets / scripts / leaker.js
Here Insert Picture Description
binding Leaker the Start button to initialize the object, and assign it to a variable global name space. Destroy button will also need to be bound to a method should be cleaned Leaker object and have it ready for garbage collection, shown in Listing 3.

Listing 3.assets / scripts / main.js
Here Insert Picture Description
Now, you are ready to create an object to see it in memory and then release it.

Load index page in Chrome. Because you are loaded jQuery directly from Google, you need an Internet connection to run the sample.

Open Developer Tools by opening the View menu and choose Develop submenu. Select Developer Tools command.

Go to the Profiles tab and get a snapshot of the heap, as shown in Fig.
Figure 2. Profiles tab,
Here Insert Picture Description
attention returned to the Web, select Start.

Get another heap snapshot.

Filtering the first snapshot, find instances Leaker class, I could not find any examples. Switching to the second snapshot, you should be able to find an example, as shown in FIG.
Figure 3. snapshot instances Here Insert Picture Description
attention returned to the Web, select Destroy.

Obtain third heap snapshots.

The third filter snapshots, find instances Leaker class, I could not find any examples.
When a third snapshot is loaded, analysis can also be switched from mode to Comparison Summary, and compare the third and the second snapshot. You will see the offset value -1 (between the two snapshots released an instance Leaker object).

Long live! Garbage collection effective. Now is the time to break it up.

A memory leak: Closures
A simple method of preventing a waste is recovered object is a reference to the object set interval or timeout callback. To see the practical application of renewable leaker.js class, as shown in Listing 4.
Listing 4.assets / scripts / leaker.js Here Insert Picture Description
Now, when Repeat steps 1-9 in the section, you should see the third snapshot, Leaker object is persistent, and the gap will continue to run forever . So what happened? In reference to a closure of any local variables will be retained to the closed package, as long as the present closure will never reserved.

To ensure setInterval callback method is performed when the access range Leaker instance, needs to be assigned to the local variable this variable self, this variable is used to trigger onInterval from the closure. When onInterval triggered, it can access any instance variables Leaker object (including its own).

However, as long as there is an event listener, Leaker object will not be garbage collected.

To resolve this problem, before emptying leaker objects stored references, triggering Add to destroy the object's method, the method is to update Destroy button's click handler, as shown in Listing 5.
Listing 5.assets / scripts / main.js
Here Insert Picture Description
destroy objects and object ownership
approach is a great way to create a standard way to make a responsible objects are eligible for garbage. The main purpose destroy functions that focus on cleaning duty operation has the following consequences of that object completed:

Stop its reference count drops to zero (for example, removing event listeners problems and callbacks, and unregister from any service).

Unnecessary use of CPU cycles, such as spacing or animation.

destroy method is often a necessary step to clean up an object, but in most cases it is not enough. In theory, after the destruction of relevant instances, the retention method for other object reference has been destroyed objects can call on their own.

Since this situation may produce unpredictable results, so the destroy method is called only when an object is about useless, which is essential.

In general, destroy the best method is to use an object in a clear owner responsible during its life cycle. This situation is often present in the layer system, such as the view MVC framework or controller, or a canvas scene rendering system of FIG.

Memory leaks 2: console log
less obvious way to preserve it in memory is to record it to the console. Listing 6 updated Leaker class, it shows an example of this approach.
Listing 6.assets / scripts / leaker.js Here Insert Picture Description
can take the following steps to demonstrate the impact of the console.

  • Log on to the index page.
  • Click Start.
  • Go to the console and make sure Leaking object has been tracked.
  • Click Destroy.
  • Back to the console and type leak, to record the current contents of the global variable. This value should be empty at the moment.
  • Get another heap snapshot and filtered Leaker object.
  • You should leave a Leaker object. Back to the console and remove it.
  • Create another heap profile.
  • After cleaning up the console, configuration files should retain the leaker has been cleared.

Console logging impact on the overall memory configuration file can be extremely important issue for many developers think of none. Error objects can record large amounts of data retained in memory. Note that this also applies to:

  • When the user types in JavaScript, an object in the console recorded during an interactive session.
  • Console.log and recorded by the method console.dir object.

Memory leak 3: cycle
when two object references to each other and to retain one another, will produce a cycle, as shown in FIG.
Figure 4. Create a reference cycle
Here Insert Picture Description
Listing 7 shows a simple code example.
Listing 7.assets / scripts / leaker.js Here Insert Picture Description
instantiated Root objects can be modified, as shown in Listing 8.
Listing 8.assets / scripts / main.js Here Insert Picture Description
If you create and execute a heap analysis after the destruction of the object, you should see the garbage collector to detect this circular reference, and release memory when you select the Destroy button.

However, if the introduction of the third to retain the sub-objects of the object, the loop will cause a memory leak. For example, create a registry objects, as shown in Listing 9.
Listing 9.assets / scripts / registry.js Here Insert Picture Description
Registry class is to allow other objects to register it, and then delete itself the object of a simple example from the registry. Although this particular class and registry unrelated, but this is an event scheduler and notification system in a common mode.

The class into index.html page, placed before leaker.js, as shown in Listing 10.
Listing 10. index.html
Here Insert Picture Description
update Leaker objects, objects to the registry to register the object itself (may be used to inform about some of the unrealized events).

This creates a sub-object from a leaker to retain the root node of the alternate path, but because of the cycle, the parent objects are also retained, as shown in Listing 11.
Listing 11. assets / scripts / leaker.js Here Insert Picture Description
Finally, main.js updated to set the registry and the registry is a reference to a parent object is passed to the leaker, as shown in Listing 12.
Listing 12.assets / scripts / main.js Here Insert Picture Description
now, when the execution stack analysis, you should see each time you select the Start button, will create and retain two new instances Leaker object. Figure 5 shows a flow of object references.
Figure 5. Due to retain a reference to a memory leak caused by
Here Insert Picture Description
the surface, it is like an unnatural example, but it is actually very common. More classic object-oriented framework in the event listeners often follow a similar pattern Figure 5. The problem with this type of pattern and may lead to closures and associated console log.

Although there are several ways to solve this problem, but in this case, the easiest way is to update Leaker class to destroy its child objects when destroy it. For this example, updating destroy method (Listing 13) is sufficient.
Listing 13.assets / scripts / leaker.js Here Insert Picture DescriptionSometimes there is not enough there will still be two cycles of the close relationship between objects, life cycle management of one of the objects of another object. In this case, the object relationship between these two objects should be responsible when they have been destroyed cycle is aborted.

Conclusion
Even if JavaScript is garbage, there will still be many ways unwanted objects will remain in memory. Currently, most browsers have improved memory cleaning function, but the assessment of your application memory heap tools are still limited (except Google Chrome).

By beginning from simple test cases, it is easy to assess the potential leakage behavior and determine whether there is a leak.

Not tested, it is impossible to accurately measure memory usage. It is easy to occupy most of the circular reference region of the object graph. Chrome's Heap Profiler is a valuable tool for the diagnosis of memory problems, use it regularly is also a good choice when developing.

Set specific expected when the prediction target graph particular resource to be released, and then verified. Whenever you see an undesired results, investigate carefully.

When you create the object to be planned cleanup of the object, which is later than in a liquidation phase transplanted into the application much easier. To schedule often removing event listeners and stop the intervals you created. If you recognize the memory usage of your application, you will be more reliable and higher performing applications.
http://www.ibm.com/developerworks/cn/web/wa-jsmemory/

About JS of memory leaks, you learn how much? Comments are welcome in the comments area!

Published 180 original articles · won praise 13 · views 7174

Guess you like

Origin blog.csdn.net/weixin_45794138/article/details/104859633