Rumah pembangunan bahagian belakang tutorial php php垃圾回收之回收计策和算法

php垃圾回收之回收计策和算法

Jun 13, 2016 pm 12:03 PM
root unset xdebug zval

php垃圾回收之回收策略和算法

一、垃圾回收实现方式

? ? ?在以前的php中用到的是引用计数机制处理垃圾回收问题,但是这个机制存在一个弊端,就是无法处理循环引用引起的内存泄露。然而在php5.3.0以后的版本中(包含5.3.0)使用了专门GC机制(同步算法)清理垃圾,来处理这个内存泄露问题。下面就是介绍它是如何实现的:

? ??首先要了解几个基本的准则:

1:如果一个zval的refcount增加,那么此zval还在使用,不属于垃圾。

2:如果一个zval的refcount减少到0,?那么zval可以被释放掉,属于垃圾。

3:如果一个zval的refcount减少之后大于0,那么此zval还不能被释放,此zval可能成为一个垃圾。

? ? ?只有在准则3下,GC才会把zval收集起来,然后通过新的算法来判断此zval是否为垃圾。那么如何判断这么一个变量是否为真正的垃圾呢?简单的说,就是对此zval中的每个元素进行一次refcount减1操作,操作完成之后,如果zval的refcount=0,那么这个zval就是一个垃圾。这个原理咋看起来很简单,但是又不是那么容易理解,下面通过结构图来深入理解:


? ? ?A:为了避免每次变量的refcount减少的时候都调用GC的算法进行垃圾判断,此算法会先把所有前面准则3情况下的zval节点放入一个节点(root)缓冲区(root buffer),并且将这些zval节点标记成紫色,同时算法必须确保每一个zval节点在缓冲区中之出现一次。当缓冲区被节点塞满的时候,GC才开始开始对缓冲区中的zval节点进行垃圾判断。

? ? ?B:当缓冲区满了之后,算法以深度优先对每一个节点所包含的zval进行减1操作,为了确保不会对同一个zval的refcount重复执行减1操作,一旦zval的refcount减1之后会将zval标记成灰色。需要强调的是,这个步骤中,起初节点zval本身不做减1操作,但是如果节点zval中包含的zval又指向了节点zval(环形引用),那么这个时候需要对节点zval进行减1操作。

? ? ?C:算法再次以深度优先判断每一个节点包含的zval的值,如果zval的refcount等于0,那么将其标记成白色(代表垃圾),如果zval的refcount大于0,那么将对此zval以及其包含的zval进行refcount加1操作,这个是对非垃圾的还原操作,同时将这些zval的颜色变成黑色(zval的默认颜色属性)

? ? ?D:遍历zval节点,将C中标记成白色的节点zval释放掉。

二、举例详解垃圾回收过程

? ? ?通过上面的说明,大家可能已经有了一定的印象,那实际应用中是如何具体操作的呢?下面就通过例子说明:

? ? ①在刚刚声明变量并赋值的情况下,其实就相当于准则1(如果一个zval的refcount增加,那么此zval还在使用,不属于垃圾),变量不是垃圾,也不会进行gc检查。

$a = "one";$b = array();$b[] = $a;$b[] = & $b;$c = "two";//声明了三个变量$a、$b、$c。这个时候refcount都是增加的情况,变量不是垃圾也不会放入到root缓冲器等待垃圾检查。xdebug_debug_zval( 'a' );  xdebug_debug_zval( 'b' );  xdebug_debug_zval( 'c' );  //输出分别如下:a: (refcount=2, is_ref=0)='one'b: (refcount=2, is_ref=1)=array (     0 => (refcount=2, is_ref=0)='one',     1 => (refcount=2, is_ref=1)=... )  c: (refcount=1, is_ref=0)='two'
Salin selepas log masuk

? ?②在上面的基础上,我们调用了unset()函数释放变量b和c。如下:

unset($b);unset($c);xdebug_debug_zval( 'a' ); //输出如下:a: (refcount=2, is_ref=0)='one'
Salin selepas log masuk

? ? ?调用unset函数后,$b和$c对应容器中的refcount都会减1,但是他们的效果却不相同:先看$c调用unset($c)后,$c的refcount就编程了0,符合准则2,则$c对应的zval容器就是垃圾会被回收;再看$b调用unset($b)后,但是$b的第1个引用仍然指向$b所对应的zval容器,只不过$b对应的zval容器的refcount会减1,值会从2变成1。这时候容器的refcount虽然减1,但仍然不为零,则符合准则3,会把$b对应的zval,放入到root缓冲区中。等待gc垃圾校验操作,也就是进入到了(二)中的(A)情况。

? ? ?③在往后的操作就是(二)中描述的了。经历(二)中的ABCD过程后,变量$b对应的zval容器会被释放,完成了垃圾回收,也解决了循环引用的内存泄露问题。

三、垃圾回收器配置使用

? ? ?在PHP中,GC默认是开启的,你可以通过ini文件中的?zend.enable_gc 项来开启或则关闭GC。当GC开启的时候,垃圾分析算法将在节点缓冲区(roots buffer)满了之后启动。缓冲区默认可以放10,000个值,当然你也可以通过修改Zend/zend_gc.c中的GC_ROOT_BUFFER_MAX_ENTRIES?来改变这个数值,需要重新编译链接PHP。当GC关闭的时候,垃圾分析算法就不会运行,但是相关节点还会被放入节点缓冲区,这个时候如果缓冲区节点已经放满,那么新的节点就不会被记录下来,这些没有被记录下来的节点就永远也不会被垃圾分析算法分析。如果这些节点中有循环引用,那么有可能产生内存泄漏。之所以在GC关闭的时候还要记录这些节点,是因为简单的记录这些节点比在每次产生节点的时候判断GC是否开启更快,另外GC是可以在脚本运行中开启的,所以记录下这些节点,在代码运行的某个时候如果又开启了GC,这些节点就能被分析算法分析。当然垃圾分析算法是一个比较耗时的操作。

??? 在PHP代码中我们可以通过gc_enable()和gc_disable()函数来开启和关闭GC,也可以通过调用gc_collect_cycles()在节点缓冲区未满的情况下强制执行垃圾分析算法。这样用户就可以在程序的某些部分关闭或则开启GC,也可强制进行垃圾分析算法。?

? ? ?

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

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Repo: Cara menghidupkan semula rakan sepasukan
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Cara mendapatkan biji gergasi
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Log masuk ke Ubuntu sebagai pengguna super Log masuk ke Ubuntu sebagai pengguna super Mar 20, 2024 am 10:55 AM

Dalam sistem Ubuntu, pengguna root biasanya dilumpuhkan. Untuk mengaktifkan pengguna root, anda boleh menggunakan arahan passwd untuk menetapkan kata laluan dan kemudian menggunakan arahan su untuk log masuk sebagai root. Pengguna akar ialah pengguna dengan hak pentadbiran sistem tanpa had. Dia mempunyai kebenaran untuk mengakses dan mengubah suai fail, pengurusan pengguna, pemasangan dan pengalihan keluar perisian, dan perubahan konfigurasi sistem. Terdapat perbezaan yang jelas antara pengguna akar dan pengguna biasa Pengguna akar mempunyai kuasa tertinggi dan hak kawalan yang lebih luas dalam sistem. Pengguna akar boleh melaksanakan perintah sistem yang penting dan mengedit fail sistem, yang tidak boleh dilakukan oleh pengguna biasa. Dalam panduan ini, saya akan meneroka pengguna akar Ubuntu, cara log masuk sebagai akar, dan bagaimana ia berbeza daripada pengguna biasa. Notis

Bagaimana untuk menukar nama pengguna root di Linux Bagaimana untuk menukar nama pengguna root di Linux May 18, 2023 pm 07:50 PM

1. Mengambil CentOS sebagai contoh, selepas log masuk, ubah suai /etc/passwd dan /etc/shadow, tukar akar bermula pada baris pertama kepada nama pengguna baharu (seperti admin), dan simpan melalui wq! 2. Selepas pengubahsuaian dan penyimpanan, ia akan berkuat kuasa selepas memulakan semula pelayan Anda boleh menyemak kebenaran fail dan melihat bahawa lajur akaun telah bertukar kepada pentadbir, seperti berikut: Nota: Pengguna lalai dengan kuasa pentadbiran tertinggi di Linux. ialah akar, uid ialah 0. Hanya uid yang diiktiraf dalam sistem, jadi selagi uid adalah 0, sistem itu dianggap sebagai pengguna pentadbiran tertinggi. Walau bagaimanapun, mungkin terdapat masalah tertentu dengan aplikasi Sesetengah perisian menggunakan pengguna akar secara lalai, jadi jika anda mempunyai pemahaman terhad tentang aplikasi perisian,

Langkah demi langkah menggunakan Python untuk memadam fail laluan panjang di bawah Windows Langkah demi langkah menggunakan Python untuk memadam fail laluan panjang di bawah Windows Apr 12, 2023 pm 01:31 PM

0x01 Latar belakang artikel Baru-baru ini, storan sistem perniagaan syarikat pengarang menghampiri had, dan pelayan tidak akan dapat dijalankan tidak lama lagi Kerana sistem perniagaan A mengandungi berbilang subsistem A1, A2, A3... Satu, bahagian tengah subsistem ini Disebabkan oleh sebab reka bentuk, semua fail storan disimpan dalam direktori induk yang sama Satu-satunya perbezaan ialah nama fail dan folder yang dijana oleh subsistem yang berbeza bermula dengan nama subsistem. Sebagai contoh, fail yang dijana oleh subsistem A1 semuanya dinamakan A1xxxxxx, dan nama fail yang dijana oleh subsistem A2 semuanya A2xxxxx. Sekarang kita perlu memadamkan fail sejarah beberapa subsistem ini untuk mengosongkan ruang pelayan Berpuluh-puluh terabait data disimpan bersama-sama Pemadaman manual pasti tidak akan muncul.

Apakah perbezaan antara arahan root dan alias dalam konfigurasi Nginx? Apakah perbezaan antara arahan root dan alias dalam konfigurasi Nginx? May 12, 2023 pm 12:16 PM

Kedua-dua akar dan alias boleh ditakrifkan dalam modul lokasi, dan digunakan untuk menentukan laluan sebenar sumber yang diminta, contohnya: lokasi/i/{root/data/w3;} permintaan http://foofish.net/i /top.gif Apabila alamat ini digunakan, sumber sebenar yang sepadan dalam pelayan ialah fail /data/w3/i/top.gif Nota: Laluan sebenar ialah nilai yang ditentukan oleh akar ditambah nilai yang ditentukan oleh lokasi. Dan alias sama seperti namanya Jalan yang ditentukan oleh alias ialah alias lokasi Tidak kira bagaimana nilai lokasi ditulis, laluan sebenar sumber ialah laluan yang ditentukan oleh alias, seperti

Kebaikan dan Keburukan Mengakar Telefon Anda Kebaikan dan Keburukan Mengakar Telefon Anda Jul 06, 2023 pm 04:53 PM

Faedah mengakar telefon anda: 1. Anda boleh membuat sandaran sistem; 2. Anda boleh menggunakan program lanjutan; fon sistem, dsb. Kelemahan: 1. Selepas telefon mudah alih di-root, ia mudah diceroboh oleh virus Trojan; 2. Kerosakan sistem mungkin berlaku kerana masalah ketidaklengkapan dan keserasian perisian 3. Selepas telefon bimbit di-root, perisian tersalah memadam fail sistem , menyebabkan ralat sistem; 4. Terdapat risiko privasi pengguna dibocorkan selepas mengakar telefon, dsb.

Adakah dengan mendayakan XDebug pada pelayan pengeluaran menjadikan PHP lebih perlahan? Adakah dengan mendayakan XDebug pada pelayan pengeluaran menjadikan PHP lebih perlahan? Sep 22, 2023 pm 10:41 PM

Ya, penyahpepijat seperti XDebug boleh memperlahankan prestasi pelayan PHP. Inilah sebabnya mengapa penyahpepijat tidak diletakkan dalam persekitaran pelayan. Mereka digunakan dalam persekitaran yang berbeza untuk mengelakkan overhed yang tidak perlu. Mesej nyahpepijat tidak boleh dipaparkan dalam aplikasi yang sudah dalam pengeluaran. Apabila tingkah laku penyahpepijatan ditambahkan pada pelayan, enjin penyahpepijatan dilampirkan pada proses PHP. Ia mula menerima mesej untuk berhenti pada titik putus, tetapi ini tidak diperlukan kelakuan kerana ia akan memberikan prestasi prestasi kepada proses lain, sekali gus menghentikan penghurai PHP. Sebaliknya, apabila penyahpepijat dipasang, mereka cenderung untuk membuka port dalam pelayan kerana ia tidak bertujuan untuk digunakan dalam persekitaran pengeluaran. Membuka port dalam pelayan anda sama buruknya dengan membuka pintu untuk penggodam mengintai.

Bagaimanakah PHP menyimpan pembolehubah? Adakah anda memahami struktur zval? Bagaimanakah PHP menyimpan pembolehubah? Adakah anda memahami struktur zval? May 26, 2022 am 09:47 AM

Tidak perlu mengisytiharkan jenis semasa mentakrifkan pembolehubah dalam PHP Anda pada mulanya menetapkan nilai integer kepada pembolehubah $a, dan anda boleh menukarnya dengan mudah kepada jenis lain kemudian. Jadi bagaimana pembolehubah ini $a disimpan dalam kod sumber PHP? Dengan memikirkan soalan ini, mari kita lihat kod sumber PHP.

Cara memasang program Linux tanpa kebenaran root Cara memasang program Linux tanpa kebenaran root Jan 13, 2024 pm 03:27 PM

Untuk sesetengah mesin kongsi, kami mungkin tidak mempunyai keizinan root, jadi ia akan menyusahkan sedikit untuk memasang program Sebenarnya, selagi fail yang berkaitan diletakkan dalam direktori mereka sendiri, sekatan kebenaran root boleh diketepikan. Saya memasang libevent tanpa kebenaran root Hanya tentukan laluan pemasangan ke direktori /home saya melalui awalan: ./configure--prefix=/home/****/libevent--enable-sharedmakemakeinstallmakeverify#libevent test, yang lain Pemasangan mungkin tidak. tersedia.

See all articles