javascript栏目教程介绍常见的内存泄漏。
- 前言
- 1 介绍
- 2 内存泄露的主要原因
- 3 常见的内存泄露
- 3.1 全局变量
- 3.2 计时器
- 3.3 多处引用
- 3.4 闭包
- 4 Chrome内存分析工具
- 资料
前言
在阅读这篇博客之前,你或许需要具备一些JavaScript内存管理的知识:
V8中JavaScript的内存管理与垃圾回收
1 介绍
内存泄露(Memory Leaks):是指应用程序已经不再需要的内存,由于某种原因未返回给操作系统或者空闲内存池(Pool of Free Memory)。
内存泄露可能带来的问题:变慢、卡顿、高延迟。
2 内存泄露的主要原因
JavaScript内存泄漏的主要原因在于一些不再需要的引用(Unwanted References)。
所谓的Unwanted References指的是:有一些内存,其实开发人员已经不再需要了,但是由于某种原因,这些内存仍然被标记并保留在活动根目录树中。Unwanted References就是指对这些内存的引用。在JavaScript上下文中,Unwanted References是一些不再使用的变量,这些变量指向了原本可以释放的一些内存。
3 常见的内存泄露
3.1 全局变量
首先,我们得知道,JavaScript中的全局变量是由根节点(root node)引用的,因此它们在应用程序的整个生命周期中都不会被垃圾回收。
场景一:在JavaScript中,如果引用未声明的变量,将会导致,在全局环境中创建新的变量。
function foo(arg) { bar = "this is a hidden global variable"; }
上面这串代码,实际上如下:
function foo(arg) { window.bar = "this is an explicit global variable"; }
假如,我们希望bar这个变量仅在foo函数作用域内部使用,但上面这种情况就会意外地在全局作用域内创建bar,这将造成内存泄漏。
场景二:
function foo() { this.variable = "potential accidental global"; }foo();
同样的,如果我们希望bar这个变量仅在foo函数作用域内部使用,但如果不知道foo函数内部的this指向全局对象,将造成内存泄露。
建议:
避免意外地创建全局变量。比如,我们可以使用严格模式,则本节的第一段代码将报错,而不会创建全局变量。
减少创建全局变量。
如果必须使用全局变量来存储大量数据,请确保在处理完数据后将其置null或重新分配。
3.2 计时器
场景举例:
for (var i = 0; i < 100000; i++) { var buggyObject = { callAgain: function () { var ref = this; var val = setTimeout(function () { ref.callAgain(); }, 10); } } buggyObject.callAgain(); buggyObject = null;}
3.3 多处引用
多处引用(Multiple references):当多个对象均引用同一对象时,但凡其中一个引用没有清除,都将导致被引用对象无法GC。
场景一:
var elements = { button: document.getElementById('button'), image: document.getElementById('image'), text: document.getElementById('text')};function doStuff() { image.src = 'http://some.url/image'; button.click(); console.log(text.innerHTML); // Much more logic}function removeButton() { // The button is a direct child of body. document.body.removeChild(document.getElementById('button')); // At this point, we still have a reference to #button in the global // elements dictionary. In other words, the button element is still in // memory and cannot be collected by the GC.s}
在上面这种情况中,我们对#button的保持两个引用:一个在DOM树中,另一个在elements对象中。 如果将来决定回收#button,则需要使两个引用均不可访问。在上面的代码中,由于我们只清除了来自DOM树的引用,所以#button仍然存在内存中,而不会被GC。
场景二: 如果我们想要回收某个table,但我们保持着对这个table中某个单元格(cell)的引用,这个时候将导致整个table都保存在内存中,无法GC。
3.4 闭包
闭包(Closure):闭包是一个函数,它可以访问那些定义在它的包围作用域(Enclosing Scope)里的变量,即使这个包围作用域已经结束。因此,闭包具有记忆周围环境(Context)的功能。
场景举例:
var newElem;function outer() { var someText = new Array(1000000); var elem = newElem; function inner() { if (elem) return someText; } return function () {}; }setInterval(function () { newElem = outer();}, 5);
在这个例子中,有两个闭包:一个是inner,另一个是匿名函数function () {}
。其中,inner闭包引用了someText和elem,并且,inner永远也不会被调用。可是,我们需要注意:相同父作用域的闭包,他们能够共享context。 也就是说,在这个例子中,inner的someText和elem将和匿名函数function () {}
共享。然而,这个匿名函数之后会被return返回,并且赋值给newElem。只要newElem还引用着这个匿名函数,那么,someText和elem就不会被GC。
同时,我们还要注意到,outer函数内部执行了var elem = newElem;
,而这个newElem引用了上一次调用的outer返回的匿名函数。试想,第n次调用outer将保持着第n-1次调用的outer中的匿名函数,而这个匿名函数由保持着对elem的引用,进而保持着对n-2次的...因此,这将造成内存泄漏。
解决方案:setInterval中的参数1的代码改为newElem = outer()();
这一节内容的具体剖析,可以见资料1和资料2。
4 Chrome内存分析工具
Chrome(最新的86版本)开发者工具中有两个关于内存的分析工具:
Performance
Memory

相关免费学习推荐:javascript(视频)
Atas ialah kandungan terperinci JavaScript常见几种的内存泄漏. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Ya, teras enjin JavaScript ditulis dalam C. 1) Bahasa C menyediakan prestasi yang efisien dan kawalan asas, yang sesuai untuk pembangunan enjin JavaScript. 2) Mengambil enjin V8 sebagai contoh, terasnya ditulis dalam C, menggabungkan kecekapan dan ciri-ciri berorientasikan objek C. 3) Prinsip kerja enjin JavaScript termasuk parsing, penyusun dan pelaksanaan, dan bahasa C memainkan peranan penting dalam proses ini.

JavaScript adalah di tengah -tengah laman web moden kerana ia meningkatkan interaktiviti dan dinamik laman web. 1) Ia membolehkan untuk menukar kandungan tanpa menyegarkan halaman, 2) memanipulasi laman web melalui Domapi, 3) menyokong kesan interaktif kompleks seperti animasi dan drag-and-drop, 4) mengoptimumkan prestasi dan amalan terbaik untuk meningkatkan pengalaman pengguna.

C dan JavaScript mencapai interoperabilitas melalui webassembly. 1) Kod C disusun ke dalam modul WebAssembly dan diperkenalkan ke dalam persekitaran JavaScript untuk meningkatkan kuasa pengkomputeran. 2) Dalam pembangunan permainan, C mengendalikan enjin fizik dan rendering grafik, dan JavaScript bertanggungjawab untuk logik permainan dan antara muka pengguna.

JavaScript digunakan secara meluas di laman web, aplikasi mudah alih, aplikasi desktop dan pengaturcaraan sisi pelayan. 1) Dalam pembangunan laman web, JavaScript mengendalikan DOM bersama -sama dengan HTML dan CSS untuk mencapai kesan dinamik dan menyokong rangka kerja seperti JQuery dan React. 2) Melalui reaktnatif dan ionik, JavaScript digunakan untuk membangunkan aplikasi mudah alih rentas platform. 3) Rangka kerja elektron membolehkan JavaScript membina aplikasi desktop. 4) Node.js membolehkan JavaScript berjalan di sisi pelayan dan menyokong permintaan serentak yang tinggi.

Python lebih sesuai untuk sains data dan automasi, manakala JavaScript lebih sesuai untuk pembangunan front-end dan penuh. 1. Python berfungsi dengan baik dalam sains data dan pembelajaran mesin, menggunakan perpustakaan seperti numpy dan panda untuk pemprosesan data dan pemodelan. 2. Python adalah ringkas dan cekap dalam automasi dan skrip. 3. JavaScript sangat diperlukan dalam pembangunan front-end dan digunakan untuk membina laman web dinamik dan aplikasi satu halaman. 4. JavaScript memainkan peranan dalam pembangunan back-end melalui Node.js dan menyokong pembangunan stack penuh.

C dan C memainkan peranan penting dalam enjin JavaScript, terutamanya digunakan untuk melaksanakan jurubahasa dan penyusun JIT. 1) C digunakan untuk menghuraikan kod sumber JavaScript dan menghasilkan pokok sintaks abstrak. 2) C bertanggungjawab untuk menjana dan melaksanakan bytecode. 3) C melaksanakan pengkompil JIT, mengoptimumkan dan menyusun kod hot-spot semasa runtime, dan dengan ketara meningkatkan kecekapan pelaksanaan JavaScript.

Aplikasi JavaScript di dunia nyata termasuk pembangunan depan dan back-end. 1) Memaparkan aplikasi front-end dengan membina aplikasi senarai TODO, yang melibatkan operasi DOM dan pemprosesan acara. 2) Membina Restfulapi melalui Node.js dan menyatakan untuk menunjukkan aplikasi back-end.

Penggunaan utama JavaScript dalam pembangunan web termasuk interaksi klien, pengesahan bentuk dan komunikasi tak segerak. 1) kemas kini kandungan dinamik dan interaksi pengguna melalui operasi DOM; 2) pengesahan pelanggan dijalankan sebelum pengguna mengemukakan data untuk meningkatkan pengalaman pengguna; 3) Komunikasi yang tidak bersesuaian dengan pelayan dicapai melalui teknologi Ajax.


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

SublimeText3 versi Inggeris
Disyorkan: Versi Win, menyokong gesaan kod!

ZendStudio 13.5.1 Mac
Persekitaran pembangunan bersepadu PHP yang berkuasa

MinGW - GNU Minimalis untuk Windows
Projek ini dalam proses untuk dipindahkan ke osdn.net/projects/mingw, anda boleh terus mengikuti kami di sana. MinGW: Port Windows asli bagi GNU Compiler Collection (GCC), perpustakaan import yang boleh diedarkan secara bebas dan fail pengepala untuk membina aplikasi Windows asli termasuk sambungan kepada masa jalan MSVC untuk menyokong fungsi C99. Semua perisian MinGW boleh dijalankan pada platform Windows 64-bit.

Penyesuai Pelayan SAP NetWeaver untuk Eclipse
Integrasikan Eclipse dengan pelayan aplikasi SAP NetWeaver.

Muat turun versi mac editor Atom
Editor sumber terbuka yang paling popular
