Rumah pembangunan bahagian belakang tutorial php 浅谈PHP源码三十三:PHP5.3新增加的垃圾回收机制(Garbage Collection)基础

浅谈PHP源码三十三:PHP5.3新增加的垃圾回收机制(Garbage Collection)基础

Jun 29, 2018 am 10:00 AM

这篇文章主要介绍了关于浅谈PHP源码三十三:PHP5.3新增加的垃圾回收机制(Garbage Collection)基础,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

浅谈PHP源码三十三:PHP5.3新增加的垃圾回收机制(Garbage Collection)基础
PHP5.3中新增加了垃圾回收机制,据说很先进,据说引诱了我去看看其先进的实现。
官方说明文档请猛击Garbage Collection
中文版地址:http://docs.php.net/manual/zh/features.gc.php
【垃圾回收机制的嵌入方式】
zend_gc.h文件在zend.h的749行被引用:#include “zend_gc.h”
从而替换覆盖了在237行引用的zend_alloc.h文件中的ALLOC_ZVAL等宏
zend/zend_gc.h文件的202行开始

 /* The following macroses override macroses from zend_alloc.h */#undef  ALLOC_ZVAL#define ALLOC_ZVAL(z) \
do {\
(z) = (zval*)emalloc(sizeof(zval_gc_info));\
GC_ZVAL_INIT(z);\
} while (0)
Salin selepas log masuk

ALLOC_ZVAL宏在zend_alloc.h中的定义是分配一个zval结构的内存空间。新的ALLOC_ZVAL宏分配了一个zval_gc_info结构的宏。zval_gc_info的结构如下:
zend/zend_gc.h文件的91行开始:

 typedef struct _zval_gc_info {
zval z;
union {
gc_root_buffer       *buffered;
struct _zval_gc_info *next;
} u;} zval_gc_info;
Salin selepas log masuk

zval_gc_info的第一个成员为zval结构,这就确保其和以zval变量分配的内存的开始对齐,从而在zval_gc_info类型指针的强制转换时,其可以作为zval使用。关于gc_root_buffer等将在后面的结构和实现时介绍,它定义的PHP垃圾回收机制的缓存结构。GC_ZVAL_INIT用来初始化替代了zval的zval_gc_info,它会把zval_gc_info中的成员u的buffered字段设置成NULL,此字段仅在将其放入垃圾回收缓冲区时才会有值,否则会一直是NULL。

由于PHP中所有的变量都是以zval变量的形式存在,这里以zval_gc_info替换zval,从而成功实现垃圾收集机制在原有系统中的集成。
这个有点面向对象中多态的感觉。

【垃圾回收机制的存储方式】
结点结构:

 typedef struct _gc_root_buffer {
struct _gc_root_buffer   *prev;/* double-linked list               */
struct _gc_root_buffer   *next;
zend_object_handle        handle;/* must be 0 for zval               */
union {
zval                 *pz;
zend_object_handlers *handlers;
} u;} gc_root_buffer;
Salin selepas log masuk

很明显(见注释,虽然PHP中的注释很少,但是有些纯粹是纠结的注释),这是一个双向链表。

在联合体中的pz变量很明显就是之前定义的多态的zval_gc_info结构,于是其在链表中的当前结点指针可以通过((zval_gc_info*)(pz))->u.buffered获取,不过在看其源码中有多处使用到这个调用方式,为何不另起一个宏呢?难道是怕宏太多,不是啊,PHP就是以宏多著称,比这个宏嵌套多的宏海了去了。不懂。另外handle等结构是特别针对对象变量的。

缓冲区是话在全局变量中的,和其它模块的全局变量一样,gc也有其自己的全局变量访问宏 GC_G(v),同样对于全局变量访问宏在是否ZTS下有不同的实现。
在zend_gc.h中定义的全局变量如下:

typedef struct _zend_gc_globals {
zend_bool         gc_enabled;/* 是否开启垃圾收集机制 */
zend_bool         gc_active;/* 是否正在进行 */ 
gc_root_buffer   *buf;/* 预分配的缓冲区数组,默认为10000(preallocated arrays of buffers)   */
gc_root_buffer    roots;/* 列表的根结点(list of possible roots of cycles) */
gc_root_buffer   *unused;/* 没有使用过的缓冲区列表(list of unused buffers)           */
gc_root_buffer   *first_unused;/* 指向第一个没有使用过的缓冲区结点(pointer to first unused buffer)   */
gc_root_buffer   *last_unused;/* 指向最后一个没有使用过的缓冲区结点,此处为标记结束用(pointer to last unused buffer)    */ 
zval_gc_info     *zval_to_free;/* 将要释放的zval变量的临时列表(temporaryt list of zvals to free) */
zval_gc_info     *free_list;/* 临时变量,需要释放的列表开头 */
zval_gc_info     *next_to_free;/* 临时变量,下一个将要释放的变量位置*/ 
zend_uint gc_runs;/* gc运行的次数统计 */
zend_uint collected;    /* gc中垃圾的个数 */ // 省略...
Salin selepas log masuk

【垃圾回收机制中的颜色标记】

 #define GC_COLOR  0x03 #define GC_BLACK  0x00#define GC_WHITE  0x01#define GC_GREY   0x02#define GC_PURPLE 0x03 #define GC_ADDRESS(v) \
((gc_root_buffer*)(((zend_uintptr_t)(v)) & ~GC_COLOR))#define GC_SET_ADDRESS(v, a) \
(v) = ((gc_root_buffer*)((((zend_uintptr_t)(v)) & GC_COLOR) | ((zend_uintptr_t)(a))))#define GC_GET_COLOR(v) \
(((zend_uintptr_t)(v)) & GC_COLOR)#define GC_SET_COLOR(v, c) \
(v) = ((gc_root_buffer*)((((zend_uintptr_t)(v)) & ~GC_COLOR) | (c)))#define GC_SET_BLACK(v) \
(v) = ((gc_root_buffer*)(((zend_uintptr_t)(v)) & ~GC_COLOR))#define GC_SET_PURPLE(v) \
(v) = ((gc_root_buffer*)(((zend_uintptr_t)(v)) | GC_PURPLE))
Salin selepas log masuk

在PHP的内存管理中我们也有看到类似的以最后位作为某种类型的标记方式。

这里以内存分配的最后两位作为整个结构的颜色标记。其中
白色表示垃圾
紫色表示已放入缓冲区
灰色表示已经进行了一次refcount的减一操作
黑色是默认颜色,正常

【zval定义的改变】
PHP3.0版本 在zend/zend.h文件中,其定义如下:

struct _zval_struct {
/* Variable information */
zvalue_value value;/* value */
zend_uint refcount__gc;
zend_uchar type;/* active type */
zend_uchar is_ref__gc;};
Salin selepas log masuk

在php3.0之前的版本,如php5.2.9版本,在zend/zend.h文件中,其定义如下:

struct _zval_struct {
/* Variable information */
zvalue_value value;/* value */
zend_uint refcount;
zend_uchar type;/* active type */
zend_uchar is_ref;};
Salin selepas log masuk

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

浅谈PHP源码三十二:PHP内存池中的emalloc/efree层与堆(heap)层

浅谈PHP源码三十一:PHP内存池中的堆(heap)层基础

浅谈PHP源码三十:PHP内存池中的存储层

Atas ialah kandungan terperinci 浅谈PHP源码三十三:PHP5.3新增加的垃圾回收机制(Garbage Collection)基础. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

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)

Artikel untuk bercakap tentang mekanisme kutipan sampah dalam php Artikel untuk bercakap tentang mekanisme kutipan sampah dalam php Aug 26, 2022 am 10:48 AM

Artikel ini akan memberi anda pemahaman yang mendalam tentang mekanisme pengumpulan sampah dalam PHP. Saya harap ia akan membantu anda!

php源码是什么 php源码是什么 Oct 11, 2019 am 09:35 AM

PHP源码指的就是PHP源代码,源代码是程序和网站的基础,而PHP即“超文本预处理器”,是一种通用开源脚本语言。

Menyahsulit pengurusan memori dan mekanisme pengumpulan sampah bahasa Go Menyahsulit pengurusan memori dan mekanisme pengumpulan sampah bahasa Go Nov 30, 2023 am 09:17 AM

Bahasa Go ialah bahasa pengaturcaraan yang cekap, selamat dan serentak Reka bentuk pengurusan memori dan mekanisme pengumpulan sampah juga merupakan ciri uniknya. Artikel ini akan menyahsulit pengurusan memori dan mekanisme pengumpulan sampah bahasa Go secara mendalam. 1. Pengurusan memori Dalam bahasa Go, pengurusan memori merangkumi dua aspek: peruntukan memori dan pelepasan memori. 1.1 Peruntukan memori Dalam bahasa Go, kami memperuntukkan memori melalui fungsi terbina dalam baharu dan buat. Antaranya, baru mengembalikan penunjuk kepada nilai sifar yang baru diperuntukkan, manakala membuat pulangan jenis tertentu dan panjangnya.

Bagaimana untuk menyelesaikan masalah biasa pelepasan memori dalam fungsi Java? Bagaimana untuk menyelesaikan masalah biasa pelepasan memori dalam fungsi Java? May 02, 2024 am 09:57 AM

Pengurusan memori dalam Java melibatkan pengumpulan sampah, tetapi masalah masih boleh timbul. Masalah biasa termasuk kebocoran memori dan pemecahan memori. Kebocoran memori disebabkan oleh objek yang memegang rujukan yang tidak lagi diperlukan dan boleh diselesaikan dengan mengelakkan rujukan bulat, menggunakan rujukan yang lemah dan mengehadkan skop pembolehubah. Pemecahan memori disebabkan oleh peruntukan yang kerap dan deallocation dan boleh diselesaikan dengan menggunakan kolam memori, kolam objek besar dan pengumpulan sampah padat. Sebagai contoh, menggunakan rujukan yang lemah boleh mengendalikan kebocoran memori dan memastikan bahawa pemungut sampah menuntut semula objek apabila ia tidak lagi diperlukan.

Masalah berjalan kod sumber PHP: penyelesaian ralat indeks Masalah berjalan kod sumber PHP: penyelesaian ralat indeks Mar 09, 2024 pm 09:24 PM

Masalah berjalan kod sumber PHP: Penyelesaian ralat indeks memerlukan contoh kod khusus PHP ialah bahasa skrip bahagian pelayan yang digunakan secara meluas yang sering digunakan untuk membangunkan tapak web dinamik dan aplikasi web. Walau bagaimanapun, kadangkala anda akan menghadapi pelbagai masalah semasa menjalankan kod sumber PHP, antaranya "ralat indeks" adalah situasi biasa. Artikel ini akan memperkenalkan beberapa punca biasa dan penyelesaian ralat indeks, dan menyediakan contoh kod khusus untuk membantu pembaca menangani masalah sedemikian dengan lebih baik. Penerangan Masalah: Semasa menjalankan program PHP

Pemahaman mendalam tentang prinsip pembangunan asas PHP: pengurusan memori dan mekanisme pengumpulan sampah Pemahaman mendalam tentang prinsip pembangunan asas PHP: pengurusan memori dan mekanisme pengumpulan sampah Sep 10, 2023 pm 02:30 PM

Pemahaman mendalam tentang prinsip pembangunan asas PHP: pengurusan memori dan mekanisme pengumpulan sampah Pengenalan: PHP, sebagai bahasa pengaturcaraan peringkat tinggi, digunakan secara meluas dalam pembangunan Web. Ramai pembangun biasa dengan sintaks dan ciri PHP, tetapi mungkin kurang memahami prinsip pembangunan asas PHP. Artikel ini akan meneroka secara mendalam pengurusan memori dan mekanisme pengumpulan sampah dalam prinsip pembangunan asas PHP untuk membantu pembaca memahami dengan lebih baik mekanisme pengendalian PHP. 1. Pengurusan memori PHP Peruntukan dan pelepasan memori Pengurusan memori dalam PHP dikendalikan oleh enjin Zend

深入解析Python中的垃圾回收机制 深入解析Python中的垃圾回收机制 Mar 29, 2018 pm 01:20 PM

得益于Python的自动垃圾回收机制,在Python中创建对象时无须手动释放。这对开发者非常友好,让开发者无须关注低层内存管理。但如果对其垃圾回收机制不了解,很多时候写出的Python代码会非常低效。

Terokai ciri pengurusan memori dan mekanisme pengumpulan sampah bahasa Go Terokai ciri pengurusan memori dan mekanisme pengumpulan sampah bahasa Go Jan 23, 2024 am 10:07 AM

Meneroka mekanisme kutipan sampah dan ciri pengurusan memori Bahasa Go Pengenalan: Dengan pembangunan Internet, pembangun mempunyai keperluan yang semakin tinggi untuk bahasa pengaturcaraan. Sebagai bahasa yang ditaip dan disusun secara statik, bahasa Go telah menarik banyak perhatian sejak penubuhannya disebabkan oleh mekanisme pengumpulan sampah yang cekap dan ciri pengurusan memori. Artikel ini bertujuan untuk meneroka secara mendalam mekanisme pengumpulan sampah bahasa Go dan ciri pengurusan memorinya, dan membantu pembaca memahami dan menggunakan ciri ini dengan lebih baik melalui contoh kod khusus. 1. Mekanisme kutipan sampah 1.1 algoritma imbasan tanda bahasa Go

See all articles