Ringkasan pengetahuan pengumpulan sampah mengenai mekanisme tersembunyi JavaScript

WBOY
Lepaskan: 2022-06-08 20:50:55
ke hadapan
2760 orang telah melayarinya

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.

Ringkasan pengetahuan pengumpulan sampah mengenai mekanisme tersembunyi JavaScript

[Cadangan berkaitan: tutorial video javascript, bahagian hadapan web]

1 🎜>

Pengumpulan sampah adalah mekanisme tersembunyi

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

2. Apakah itu sampah

Kod dilaksanakan dalam memori komputer Semua pembolehubah, objek dan fungsi yang kami tentukan dalam kod akan menduduki sejumlah ruang memori dalam memori. Dalam komputer, ruang memori adalah sumber yang sangat ketat Kita mesti sentiasa memberi perhatian kepada penggunaan memori Lagipun, modul memori adalah sangat mahal. Pembolehubah, fungsi atau objek boleh dipanggil sampah jika ia tidak lagi diperlukan untuk pelaksanaan kod berikutnya selepas penciptaan.

Walaupun sangat mudah untuk memahami definisi sampah secara intuitif, untuk program komputer, sukar untuk kita membuat kesimpulan pada masa tertentu bahawa pembolehubah, fungsi atau objek yang sedia ada tidak akan digunakan lagi dalam masa depan. Untuk mengurangkan kos ingatan komputer dan memastikan pelaksanaan biasa program komputer, kami biasanya menetapkan bahawa objek atau pembolehubah yang memenuhi mana-mana syarat berikut adalah sampah:

    Objek atau pembolehubah yang bukan dirujuk;
  1. Objek yang tidak boleh diakses (rujukan bulat antara berbilang objek); gunakan mereka lagi. Walaupun objek tidak boleh diakses disambungkan, ia masih tidak boleh diakses dari luar dan oleh itu tidak boleh digunakan semula. Objek atau pembolehubah yang memenuhi syarat di atas tidak akan digunakan lagi dalam pelaksanaan program pada masa hadapan, jadi ia boleh dianggap dengan selamat sebagai kutipan sampah.
Apabila kita menjelaskan objek yang perlu dibuang melalui definisi di atas, adakah ia bermakna tiada sampah dalam pembolehubah dan objek yang tinggal?

Tidak! Sampah yang kami kenal pasti pada masa ini hanyalah sebahagian daripada semua sampah masih akan ada sampah lain yang tidak memenuhi syarat di atas, tetapi ia tidak akan digunakan lagi.

Bolehkah 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 (
) 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 dipanggil

kebocoran ingatan

. Kebocoran memori adalah fenomena yang sangat berbahaya, terutamanya dalam program yang berjalan lama. Jika program mempunyai kebocoran memori, ia akan menduduki lebih banyak ruang memori sehingga ia kehabisan memori.

GC,Garbage CollectionString, 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

akan sesekali memeriksa pembolehubah dan objek yang tidak berguna (sampah) dan melepaskan ruang yang mereka duduki.

4. Kebolehcapaian

JavaScriptBahasa pengaturcaraan yang berbeza menggunakan strategi pengumpulan sampah yang berbeza, contohnya,

tidak mempunyai mekanisme pengumpulan sampah , yang telah mengakibatkan

agak sukar untuk dikuasai.

Gunakan

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:

  1. Konteks fungsi yang sedang dilaksanakan (termasuk pembolehubah setempat dalam fungsi, parameter fungsi, dll.);
  2. Fungsi lain pada rantai panggilan bersarang semasa, pembolehubah setempat dan parameternya; ;
  3. Pembolehubah global;
  4. Pembolehubah dalaman yang lain; pokok.
Jika pembolehubah atau objek digunakan secara langsung atau tidak langsung oleh pembolehubah punca, pembolehubah itu dianggap boleh dicapai.

Dalam erti kata lain, nilai boleh dicapai jika ia boleh diakses melalui akar (contohnya, ).

5. Contoh kebolehcapaian

A.b.c.d.ePerkaitan hierarki:

Kod di atas mencipta objek dan menetapkannya kepada pembolehubah , pembolehubah mengandungi dua objek

dan
let people = {
    boys:{
        boys1:{name:'xiaoming'},
        boys2:{name:'xiaojun'},
    },
    girls:{
        girls1:{name:'xiaohong'},
        girls2:{name:'huahua'},
    }};
Salin selepas log masuk
, dan

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: boysgirlsboysgirls3di mana,

Nod secara semula jadi boleh dicapai kerana ia adalah pembolehubah global. Nod

dan Ringkasan pengetahuan pengumpulan sampah mengenai mekanisme tersembunyi JavaScript 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. boys1boys2Jika kita menambah kod berikut selepas kod di atas: girls1girls2people.boys.boysMaka rajah hierarki rujukan di atas akan menjadi seperti berikut:

people.girls.girls2 = null;people.girls.girls1 = people.boys.boys2;
Salin selepas log masuk

Antaranya,

dan

telah menjadi nod yang tidak dapat dicapai kerana terputus sambungan daripada nod Ringkasan pengetahuan pengumpulan sampah mengenai mekanisme tersembunyi JavaScript, yang bermaksud ia akan dikitar semula oleh mekanisme pengumpulan sampah.

Jika pada masa ini, kami melaksanakan kod berikut: girls1girls2grilsMaka rajah hierarki rujukan akan menjadi seperti berikut:

people.boys.boys2 = null;
Salin selepas log masuk
Pada masa ini masa , walaupun nod

dan nod
terputus, disebabkan hubungan rujukan antara nod Ringkasan pengetahuan pengumpulan sampah mengenai mekanisme tersembunyi JavaScript dan nod

,

masih boleh dicapai dan tidak akan dikitar semula oleh sampah mekanisme pengumpulan. boysboys2boys2Rajah perkaitan di atas membuktikan mengapa nilai setara pembolehubah global dipanggil girlsakarboys2, kerana dalam rajah perkaitan, nilai jenis ini biasanya muncul sebagai nod punca perhubungan pokok.

adalah berkaitan antara satu sama lain:

Kod di atas mewujudkan hubungan yang saling berkaitan antara
dan

Gambar rajah struktur hubungan adalah seperti berikut:

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
Salin selepas log masuk

boys2girls1Pada ketika ini, jika kita memutuskan perkaitan antara

dan

: Ringkasan pengetahuan pengumpulan sampah mengenai mekanisme tersembunyi JavaScript

Rajah perkaitan antara objek adalah seperti berikut: boys boys2

delete people.boys.boys2;
Salin selepas log masuk

Jelas sekali, tiada nod yang tidak boleh dicapai muncul.

Pada masa ini, jika kita memutuskan Ringkasan pengetahuan pengumpulan sampah mengenai mekanisme tersembunyi JavaScript sambungan perhubungan:

Graf perhubungan menjadi:

boyfriend

delete people.girls.girls1;
Salin selepas log masuk

Pada masa ini, Walaupun masih terdapat hubungan

antara

dan Ringkasan pengetahuan pengumpulan sampah mengenai mekanisme tersembunyi JavaScript,

dan nod yang menjadi tidak dapat dicapai akan dituntut semula oleh mekanisme kutipan sampah.

boys2girls1Pulau yang boleh diakses: girlfriendboys2

Rajah hierarki rujukan yang dibentuk oleh kod di atas adalah seperti berikut:

let people = {
    boys:{
        boys1:{name:'xiaoming'},
        boys2:{name:'xiaojun'},
    },
    girls:{
        girls1:{name:'xiaohong'},
        girls2:{name:'huahua'},
    }};delete people.boys;delete people.girls;
Salin selepas log masuk

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

akar

dan menjadi tidak dapat dicapai. Ringkasan pengetahuan pengumpulan sampah mengenai mekanisme tersembunyi JavaScript

6. Algoritma pengumpulan sampah

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

Contohnya:

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;
Salin selepas log masuk

以上代码在boygirl之间存在相互引用,计数删掉boygirl内的引用,二者对象并不会被回收。由于循环引用的存在,两个匿名对象的引用计数永远不会归零,也就产生了内存泄漏。

C++中存在一个智能指针shared_ptr)的概念,程序员可以通过智能指针,利用对象析构函数释放引用计数。但是对于循环引用的状况就会产生内存泄漏。

好在JavaScript已经采用了另外一种更为安全的策略,更大程度上避免了内存泄漏的风险。

标记清除

标记清除mark and sweep)是JavaScript引擎采取的垃圾回收算法,其基本原理是从出发,广度优先遍历变量之间的引用关系,对于遍历过的变量打上一个标记(优秀员工徽章),最后删除没有标记的对象。

算法基本过程如下:

  1. 垃圾收集器找到所有的,并颁发优秀员工徽章(标记);
  2. 然后它遍历优秀员工,并将优秀员工引用的对象同样打上优秀员工标记;
  3. 反复执行第2步,直至无新的优秀员工加入;
  4. 没有被标记的对象都会被删除。

举个栗子:

如果我们程序中存在如下图所示的对象引用关系:

Ringkasan pengetahuan pengumpulan sampah mengenai mekanisme tersembunyi JavaScript

我们可以清晰的看到,在整个图片的右侧存在一个“可达孤岛”,从出发,永远无法到达孤岛。但是垃圾回收器并没有我们这种上帝视角,它们只会根据算法会首先把根节点打上优秀员工标记。

Ringkasan pengetahuan pengumpulan sampah mengenai mekanisme tersembunyi JavaScript

然后从优秀员工出发,找到所有被优秀员工引用的节点,如上图中虚线框中的三个节点。然后把新找到的节点同样打上优秀员工标记。

Ringkasan pengetahuan pengumpulan sampah mengenai mekanisme tersembunyi JavaScript

反复执行查找和标记的过程,直至所有能找到的节点都被成功标记。

Ringkasan pengetahuan pengumpulan sampah mengenai mekanisme tersembunyi JavaScript

最终达到下图所示的效果:

Ringkasan pengetahuan pengumpulan sampah mengenai mekanisme tersembunyi JavaScript

由于在算法执行周期结束之后,右侧的孤岛仍然没有标记,因此会被垃圾回收器任务无法到达这些节点,最终被清除。

如果学过数据结构和算法的童鞋可能会惊奇的发现,这不就是图的遍历吗,类似于连通图算法。

七、性能优化

垃圾回收是一个规模庞大的工作,尤其在代码量非常大的时候,频繁执行垃圾回收算法会明显拖累程序的执行。JavaScript算法在垃圾回收上做了很多优化,从而在保证回收工作正常执行的前提下,保证程序能够高效的执行。

性能优化采取的策略通常包括以下几点:

分代回收

JavaScript程序在执行过程中会维持相当量级的变量数目,频繁扫描这些变量会造成明显的开销。但是这些变量在生命周期上各有特点,例如局部变量会频繁的创建,迅速的使用,然后丢弃,而全局变量则会长久的占据内存。JavaScript把两类对象分开管理,对于快速创建、使用并丢弃的局部变量,垃圾回收器会频繁的扫描,保证这些变量在失去作用后迅速被清理。而对于哪些长久把持内存的变量,降低检查它们的频率,从而节约一定的开销。

增量收集

增量式的思想在性能优化上非常常见,同样可以用于垃圾回收。在变量数目非常大时,一次性遍历所有变量并颁发优秀员工标记显然非常耗时,导致程序在执行过程中存在卡顿。所以,引擎会把垃圾回收工作分成多个子任务,并在程序执行的过程中逐步执行每个小任务,这样就会造成一定的回收延迟,但通常不会造成明显的程序卡顿。

Koleksi terbiar

CPUWalaupun dalam program yang kompleks, ia tidak selalu berfungsi, terutamanya kerana CPUberfungsi 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.

8. Ringkasan

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:

  1. Pengumpulan sampah adalah salah satu ciri JavaScript Ia dilaksanakan di latar belakang dan kami tidak perlu risau ia;
  2. Pengumpulan sampah Strategi ini adalah tanda dan jelas, yang menapis dan membuang sampah mengikut teori kebolehcapaian
  3. Strategi tanda jelas boleh mengelakkan kebocoran memori yang disebabkan oleh pulau yang boleh dicapai

[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!

Label berkaitan:
sumber:csdn.net
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan