Artikel ini membawa anda pengetahuan yang berkaitan tentang javascript, yang terutamanya memperkenalkan isu-isu yang berkaitan dengan pengumpulan sampah adalah mekanisme tersembunyi JavaScript. Saya harap ia akan membantu kepada semua orang.
[Cadangan berkaitan: tutorial video javascript, bahagian hadapan web]
Kita biasanya tidak perlu risau tentang kutipan sampah, kita hanya perlu fokus pada pembangunan fungsi. Tetapi ini tidak bermakna bahawa kita boleh duduk dan berehat semasa menulis JavaScript
Apabila fungsi yang kita laksanakan menjadi semakin kompleks dan jumlah kod terkumpul, masalah prestasi menjadi semakin ketara. Cara menulis kod yang dilaksanakan dengan lebih pantas dan menggunakan kurang memori adalah usaha pengaturcara yang tidak berkesudahan. Seorang pengaturcara yang cemerlang sentiasa boleh mencapai hasil yang menakjubkan dengan sumber yang sangat terhad Ini juga perbezaan antara makhluk biasa dan tuhan yang menyendiri. JavaScript
) bertanggungjawab untuk mengitar semula pembolehubah tidak berguna dan ruang memori yang diduduki semasa pelaksanaan program. Fenomena bahawa objek masih wujud dalam ingatan walaupun ia tidak mempunyai kemungkinan untuk digunakan semula dipanggilBolehkah dikatakan sampah yang memenuhi definisi di atas adalah "sampah mutlak", dan sampah lain yang tersembunyi dalam program itu adalah "sampah relatif"?
3. Pengumpulan Sampah Mekanisme pengumpulan sampah (
GC,Garbage Collection
String, objek dan tatasusunan tidak mempunyai saiz tetap, jadi peruntukan storan dinamik untuknya hanya boleh dilakukan apabila saiznya diketahui. Setiap kali program JavaScript mencipta rentetan, tatasusunan atau objek, jurubahasa memperuntukkan memori untuk menyimpan entiti. Apabila memori diperuntukkan secara dinamik seperti ini, ia mesti dibebaskan akhirnya supaya ia boleh digunakan semula jika tidak, penterjemah JavaScript akan menggunakan semua memori yang tersedia dalam sistem, menyebabkan sistem ranap; Mekanisme pengumpulan sampah
JavaScript
Bahasa pengaturcaraan yang berbeza menggunakan strategi pengumpulan sampah yang berbeza, contohnya,
kebolehcapaianC
untuk mengurus memori Secara harfiah, kebolehcapaian bermaksud boleh dicapai, yang bermaksud bahawa program boleh mengakses dan menggunakan pembolehubah dan objek dalam beberapa cara Pembolehubah ini adalah Memori yang diduduki tidak boleh dilepaskan. C
JavaScript
menentukan set nilai yang boleh dicapai secara semula jadi dan nilai dalam set itu boleh dicapai secara semula jadi:
Dalam erti kata lain, nilai boleh dicapai jika ia boleh diakses melalui akar (contohnya, ).
5. Contoh kebolehcapaian
A.b.c.d.e
Perkaitan hierarki:
let people = { boys:{ boys1:{name:'xiaoming'}, boys2:{name:'xiaojun'}, }, girls:{ girls1:{name:'xiaohong'}, girls2:{name:'huahua'}, }};
dan people
masing-masing mengandungi dua sub-objek. Ini juga mencipta struktur data yang mengandungi hubungan rujukan lapisan people
(tanpa mengambil kira data jenis asas), seperti yang ditunjukkan di bawah: boys
girls
boys
girls
3
di mana,
dan secara tidak langsung boleh dicapai kerana ia dirujuk secara langsung oleh pembolehubah global.
,, people
dan boys
juga merupakan pembolehubah boleh dicapai kerana ia digunakan secara tidak langsung oleh pembolehubah global dan boleh diakses melalui girls
. boys1
boys2
Jika kita menambah kod berikut selepas kod di atas: girls1
girls2
people.boys.boys
Maka rajah hierarki rujukan di atas akan menjadi seperti berikut:
people.girls.girls2 = null;people.girls.girls1 = people.boys.boys2;
Antaranya,
dantelah menjadi nod yang tidak dapat dicapai kerana terputus sambungan daripada nod , yang bermaksud ia akan dikitar semula oleh mekanisme pengumpulan sampah.
Jika pada masa ini, kami melaksanakan kod berikut: girls1
girls2
grils
Maka rajah hierarki rujukan akan menjadi seperti berikut:
people.boys.boys2 = null;
dan nod
terputus, disebabkan hubungan rujukan antara nod dan nod
masih boleh dicapai dan tidak akan dikitar semula oleh sampah mekanisme pengumpulan. boys
boys2
boys2
Rajah perkaitan di atas membuktikan mengapa nilai setara pembolehubah global dipanggil girls
akarboys2
, kerana dalam rajah perkaitan, nilai jenis ini biasanya muncul sebagai nod punca perhubungan pokok.
danadalah berkaitan antara satu sama lain:
Kod di atas mewujudkan hubungan yang saling berkaitan antara
let people = { boys:{ boys1:{name:'xiaoming'}, boys2:{name:'xiaojun'}, }, girls:{ girls1:{name:'xiaohong'}, girls2:{name:'huahua'}, }};people.boys.boys2.girlfriend = people.girls.girls1; //boys2引用girls1people.girls.girls1.boyfriend = people.boys.boys2; //girls1引用boys2
boys2
girls1
Pada ketika ini, jika kita memutuskan perkaitan antara
:
Rajah perkaitan antara objek adalah seperti berikut: boys
boys2
delete people.boys.boys2;
Jelas sekali, tiada nod yang tidak boleh dicapai muncul.
Pada masa ini, jika kita memutuskan sambungan perhubungan:
Graf perhubungan menjadi:boyfriend
delete people.girls.girls1;
Pada masa ini, Walaupun masih terdapat hubungan
antaradan ,
dan nod yang menjadi tidak dapat dicapai akan dituntut semula oleh mekanisme kutipan sampah.boys2
girls1
Pulau yang boleh diakses: girlfriend
boys2
let people = { boys:{ boys1:{name:'xiaoming'}, boys2:{name:'xiaojun'}, }, girls:{ girls1:{name:'xiaohong'}, girls2:{name:'huahua'}, }};delete people.boys;delete people.girls;
Ini Pada masa ini, walaupun masih terdapat hubungan rujukan bersama antara objek di dalam kotak bertitik, objek ini juga tidak boleh dicapai dan akan dipadamkan oleh mekanisme pengumpulan sampah. Nod ini telah kehilangan hubungannya dengan
akardan menjadi tidak dapat dicapai.
6. Algoritma pengumpulan sampahPengiraan rujukan
Apa yang dipanggil pengiraan rujukan, seperti namanya, ialah mengira setiap kali objek dirujuk Apabila rujukan ditambah, ia ditambah satu, dan apabila rujukan dipadamkan, ia dikurangkan dengan satu Jika bilangan rujukan menjadi 0, ia dianggap sampah, dan objek dipadamkan untuk menuntut semula memori. .Walaupun kaedah pengiraan rujukan kelihatan sangat munasabah, sebenarnya, mekanisme kitar semula memori menggunakan kaedah pengiraan rujukan mempunyai kelemahan yang jelas.
Contohnya:
let boy = {}; let girl = {}; boy.girlfriend = girl; girl.boyfriend = boy; boy = null; girl = null;
以上代码在boy
和girl
之间存在相互引用,计数删掉boy
和girl
内的引用,二者对象并不会被回收。由于循环引用的存在,两个匿名对象的引用计数永远不会归零,也就产生了内存泄漏。
在C++
中存在一个智能指针(shared_ptr
)的概念,程序员可以通过智能指针,利用对象析构函数释放引用计数。但是对于循环引用的状况就会产生内存泄漏。
好在JavaScript
已经采用了另外一种更为安全的策略,更大程度上避免了内存泄漏的风险。
标记清除(mark and sweep
)是JavaScript
引擎采取的垃圾回收算法,其基本原理是从根出发,广度优先遍历变量之间的引用关系,对于遍历过的变量打上一个标记(优秀员工徽章
),最后删除没有标记的对象。
算法基本过程如下:
2
步,直至无新的优秀员工加入;举个栗子:
如果我们程序中存在如下图所示的对象引用关系:
我们可以清晰的看到,在整个图片的右侧存在一个“可达孤岛”,从根出发,永远无法到达孤岛。但是垃圾回收器并没有我们这种上帝视角,它们只会根据算法会首先把根节点打上优秀员工标记。
然后从优秀员工出发,找到所有被优秀员工引用的节点,如上图中虚线框中的三个节点。然后把新找到的节点同样打上优秀员工标记。
反复执行查找和标记的过程,直至所有能找到的节点都被成功标记。
最终达到下图所示的效果:
由于在算法执行周期结束之后,右侧的孤岛仍然没有标记,因此会被垃圾回收器任务无法到达这些节点,最终被清除。
如果学过数据结构和算法的童鞋可能会惊奇的发现,这不就是图的遍历吗,类似于连通图算法。
垃圾回收是一个规模庞大的工作,尤其在代码量非常大的时候,频繁执行垃圾回收算法会明显拖累程序的执行。JavaScript
算法在垃圾回收上做了很多优化,从而在保证回收工作正常执行的前提下,保证程序能够高效的执行。
性能优化采取的策略通常包括以下几点:
JavaScript
程序在执行过程中会维持相当量级的变量数目,频繁扫描这些变量会造成明显的开销。但是这些变量在生命周期上各有特点,例如局部变量会频繁的创建,迅速的使用,然后丢弃,而全局变量则会长久的占据内存。JavaScript
把两类对象分开管理,对于快速创建、使用并丢弃的局部变量,垃圾回收器会频繁的扫描,保证这些变量在失去作用后迅速被清理。而对于哪些长久把持内存的变量,降低检查它们的频率,从而节约一定的开销。
增量式的思想在性能优化上非常常见,同样可以用于垃圾回收。在变量数目非常大时,一次性遍历所有变量并颁发优秀员工标记显然非常耗时,导致程序在执行过程中存在卡顿。所以,引擎会把垃圾回收工作分成多个子任务,并在程序执行的过程中逐步执行每个小任务,这样就会造成一定的回收延迟,但通常不会造成明显的程序卡顿。
CPU
Walaupun dalam program yang kompleks, ia tidak selalu berfungsi, terutamanya kerana CPU
berfungsi dengan sangat pantas, persisianIO
selalunya beberapa urutan magnitud lebih perlahan, jadi mengatur strategi kutipan sampah apabila CPU
terbiar ialah kaedah pengoptimuman prestasi yang sangat berkesan, dan pada dasarnya tidak akan memberi sebarang kesan buruk pada program itu sendiri. Strategi ini serupa dengan peningkatan masa terbiar sistem dan pengguna tidak mengetahui pelaksanaan latar belakang sama sekali.
Tugas utama artikel ini adalah untuk menamatkan mekanisme kutipan sampah, strategi yang biasa digunakan dan kaedah pengoptimuman prinsip pelaksanaan latar belakang enjin.
Melalui artikel ini, anda harus memahami:
JavaScript
Ia dilaksanakan di latar belakang dan kami tidak perlu risau ia; [Cadangan berkaitan: tutorial video javascript, bahagian hadapan web]
Atas ialah kandungan terperinci Ringkasan pengetahuan pengumpulan sampah mengenai mekanisme tersembunyi JavaScript. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!