


A brief discussion on the evolution of the garbage collection algorithm (Garbage Collection) in PHP5_PHP Tutorial
Jul 21, 2016 pm 02:52 PMForeword: PHP is a managed language. In PHP programming, programmers do not need to manually handle the allocation and release of memory resources (except when using C to write PHP or Zend extensions), which means that PHP itself implements The garbage collection mechanism (Garbage Collection) is implemented. Now if you go to the official PHP website (php.net) you can see that the current two branch versions of PHP5, PHP5.2 and PHP5.3, are updated separately. This is because many projects still use the 5.2 version of PHP, and the 5.3 version is 5.2 is not fully compatible. PHP5.3 has made many improvements based on PHP5.2, among which the garbage collection algorithm is a relatively big change. This article will discuss the garbage collection mechanisms of PHP5.2 and PHP5.3 respectively, and discuss the impact of this evolution and improvement on programmers writing PHP and the issues they should pay attention to.
Internal representation of PHP variables and associated memory objects
In the final analysis, garbage collection is the operation of variables and their associated memory objects, so before discussing PHP’s garbage collection mechanism, let’s briefly introduce the internal representation of variables and their memory objects in PHP (its representation in the C source code ).
The official PHP documentation divides variables in PHP into two categories: scalar types and complex types. Scalar types include booleans, integers, floating point types and strings; complex types include arrays, objects and resources; there is also a special NULL, which is not divided into any type, but becomes a separate category.
All these types are uniformly represented by a structure called zval within PHP. In the PHP source code, the name of this structure is "_zval_struct". The specific definition of zval is in the "Zend/zend.h" file of the PHP source code. The following is an excerpt of the relevant code.
|
The union "_zvalue_value" is used to represent the values ??of all variables in PHP. The reason why union is used here is because a zval can only represent one type of variable at a time. You can see that there are only 5 fields in _zvalue_value, but there are 8 data types in PHP including NULL. So how does PHP use 5 fields to represent 8 types internally? This is one of the more clever aspects of PHP design. It achieves the purpose of reducing fields by reusing fields. For example, within PHP, Boolean types, integers and resources (as long as the identifier of the resource is stored) are stored through the lval field; dval is used to store floating point types; str stores strings; ht stores arrays (note that in PHP The array is actually a hash table); and obj stores the object type; if all fields are set to 0 or NULL, it means NULL in PHP, so that 5 fields are used to store 8 types of values.
What type the value in the current zval (the type of value is _zvalue_value) represents is determined by the type in "_zval_struct". _zval_struct is the specific implementation of zval in C language. Each zval represents a memory object of a variable. In addition to value and type, you can see that there are two fields refcount__gc and is_ref__gc in _zval_struct. From their suffixes, you can conclude that these two guys are related to garbage collection. That's right, PHP's garbage collection relies entirely on these two fields. Among them, refcount__gc indicates that there are several variables currently referencing this zval, and is_ref__gc indicates whether the current zval is referenced by reference. This sounds very confusing. This is related to the "Write-On-Copy" mechanism of zval in PHP. Since this topic is not This article is the focus, so I won’t go into details here. Readers only need to remember the role of the refcount__gc field.
Garbage collection algorithm in PHP5.2——Reference Counting
The memory recycling algorithm used in PHP5.2 is the famous Reference Counting. The Chinese translation of this algorithm is called "reference counting". Its idea is very intuitive and concise: assign a counter to each memory object. When a memory object is created The counter is initialized to 1 (so there is always a variable referencing this object at this time). Every time a new variable refers to this memory object, the counter increases by 1, and every time a variable that references this memory object is reduced, the counter decreases by 1. When the garbage collection mechanism operates, all memory objects with a counter of 0 are destroyed and the memory they occupy is reclaimed. The memory object in PHP is zval, and the counter is refcount__gc.
For example, the following piece of PHP code demonstrates the working principle of the PHP5.2 counter (the counter value is obtained through xdebug.org):
$val1 = 100; //zval(val1).refcount_gc = 1; $val2 = $val1; //zval(val1).refcount_gc = 2,zval(val2).refcount_gc = 2 (because it is Write on copy, currently val2 and val1 jointly reference a zval) $val2 = 200; //zval(val1).refcount_gc = 1,zval(val2).refcount_gc = 1 (val2 creates a new zval here) unset($val1); //zval(val1).refcount_gc = 0 (the zval referenced by $val1 is no longer available and will be recycled by GC) ?> |
Reference Counting is simple, intuitive, and easy to implement, but it has a fatal flaw, which is that it can easily cause memory leaks. Many friends may have realized that if there is a circular reference, Reference Counting may cause memory leaks. For example, the following code:
|
$a = array(); $a[] ??= & $a; unset($a); ?> |
This code first creates the array a, and then lets the first element of a point to a by reference. At this time, the refcount of zval of a becomes 2. Then we destroy the variable a. At this time, the zval that a initially points to The refcount is 1, but we can no longer operate on it because it forms a circular self-reference, as shown in the figure below:
The gray part means it no longer exists. Since the refcount of the zval pointed to by a is 1 (referenced by the first element of its HashTable), this zval will not be destroyed by GC, and this part of the memory will be leaked.
What is particularly important to point out here is that PHP stores variable symbols through a symbol table (Symbol Table). There is a global symbol table, and each complex type such as an array or object has its own symbol table. Therefore, in the above code, a and a[0] are two symbols, but a is stored in the global symbol table, and a[0] is stored in the symbol table of the array itself, and here a and a[0] refer to the same zval (of course the symbol a was later destroyed). I hope readers will pay attention to distinguishing the relationship between symbol (Symbol) and zval.
When PHP is only used for dynamic page scripts, this leakage may not be very important, because the life cycle of dynamic page scripts is very short, and PHP will ensure that all its resources are released when the script is executed. However, PHP has developed to the point where it is no longer just used as a dynamic page script. If PHP is used in scenarios with a long life cycle, such as automated test scripts or deamon processes, the memory leaks accumulated after many cycles may be It will be serious. This is not sensational. A company I once interned with used a deamon process written in PHP to interact with the data storage server.
Due to this flaw in Reference Counting, PHP5.3 improved the garbage collection algorithm.
Garbage collection algorithm in PHP5.3 - Concurrent Cycle Collection in Reference Counted Systems
The garbage collection algorithm of PHP5.3 is still based on reference counting, but it no longer uses simple counting as the recycling criterion, but uses a synchronous recycling algorithm. This algorithm was proposed by IBM engineers in the paper Concurrent Cycle Collection in Reference Counted Systems.
This algorithm is quite complex. I think everyone can tell from the 29 pages of the paper, so I do not intend (and do not have the ability) to fully discuss this algorithm. Interested friends can read the paper mentioned above ( Highly recommended, the paper is brilliant).
I can only briefly describe the basic idea of ??this algorithm here.
First, PHP will allocate a fixed-size "root buffer". This buffer is used to store a fixed number of zvals. The default number is 10,000. If you need to modify it, you need to modify the source code Zend/zend_gc.c The constant GC_ROOT_BUFFER_MAX_ENTRIES and then recompile.
From the above we can know that if a zval has a reference, it will either be referenced by a symbol in the global symbol table or by a symbol in other zvals that represent complex types. So there are some possible roots in zval. Here we will not discuss how PHP discovers these possible roots. This is a very complex problem. In short, PHP has a way to discover these possible root zvals and put them into the root buffer.
When the root buffer is full, PHP will perform garbage collection. The recycling algorithm is as follows:
1. For the root zval in each root buffer, traverse all zvals that can be traversed according to the depth-first traversal algorithm, and decrement the refcount of each zval by 1. At the same time, in order to avoid decrementing the same zval by 1 multiple times (because Different roots may traverse the same zval). Each time a zval is decremented by 1, it is marked as "decremented".
2. Traverse the root zval in each buffer depth-first again. If the refcount of a zval is not 0, add 1 to it, otherwise keep it at 0.
3. Clear all roots in the root buffer (note that these zvals are cleared from the buffer instead of destroying them), then destroy all zvals with a refcount of 0, and reclaim their memory.
It’s okay if you don’t fully understand it. Just remember that the garbage collection algorithm of PHP5.3 has the following characteristics:
1. The recycling cycle does not start every time the refcount decreases. Garbage collection only starts after the root buffer is full.
2. Can solve the circular reference problem.
3. Memory leaks can always be kept below a threshold.
Performance comparison of garbage collection algorithms between PHP5.2 and PHP5.3
Due to my current limitations, I will not redesign the experiment, but directly quote the experiment in the PHP Manual. For a performance comparison between the two, please refer to the relevant chapters in the PHP Manual: http://www.php .net/manual/en/features.gc.performance-considerations.php.
The first is the memory leak test. The experimental code and test result diagram in the PHP Manual are directly quoted below:
{ ??? public $var = '3.1415962654'; } $baseMemory = memory_get_usage(); for ( $i = 0; $i { ??? $a = new Foo; ??? $a->self = $a; ??? if ( $i % 500 === 0 ) ??? { ??????? echo sprintf( '%8d: ', $i ), memory_get_usage() - $baseMemory, "n"; ??? } } ?> |
可以看到在可能引發(fā)累積性內(nèi)存泄露的場景下,PHP5.2發(fā)生持續(xù)累積性內(nèi)存泄露,而PHP5.3則總能將內(nèi)存泄露控制在一個(gè)閾值以下(與根緩沖區(qū)大小有關(guān))。
另外是關(guān)于性能方面的對比:
class Foo |
class Foo { ??? public $var = '3.1415962654'; } for ( $i = 0; $i { ??? $a = new Foo; ??? $a->self = $a; } echo memory_get_peak_usage(), "n"; ?>
|
這個(gè)腳本執(zhí)行1000000次循環(huán),使得延遲時(shí)間足夠進(jìn)行對比,然后使用CLI方式分別在打開內(nèi)存回收和關(guān)閉內(nèi)存回收的的情況下運(yùn)行此腳本:
time php -dzend.enable_gc=0 -dmemory_limit=-1 -n example2.php |
time php -dzend.enable_gc=0 -dmemory_limit=-1 -n example2.php |
在我的機(jī)器環(huán)境下,運(yùn)行時(shí)間分別為6.4s和7.2s,可以看到PHP5.3的垃圾回收機(jī)制會慢一些,但是影響并不大。
與垃圾回收算法相關(guān)的PHP配置
可以通過修改php.ini中的zend.enable_gc來打開或關(guān)閉PHP的垃圾回收機(jī)制,也可以通過調(diào)用gc_enable( )或gc_disable( )打開或關(guān)閉PHP的垃圾回收機(jī)制。在PHP5.3中即使關(guān)閉了垃圾回收機(jī)制,PHP仍然會記錄可能根到根緩沖區(qū),只是當(dāng)根緩沖區(qū)滿額時(shí),PHP不會自動(dòng)運(yùn)行垃圾回收,當(dāng)然,任何時(shí)候您都可以通過手工調(diào)用gc_collect_cycles( )函數(shù)強(qiáng)制執(zhí)行內(nèi)存回收。
本文基于署名-非商業(yè)性使用 3.0許可協(xié)議發(fā)布,歡迎轉(zhuǎn)載,演繹,但是必須保留本文的署名張洋(包含鏈接),且不得用戶商業(yè)目的。
前言:PHP是一門托管型語言,在PHP編程中程序員不需要手工處理內(nèi)存資源的分配與釋放(使用C編寫PHP或Zend擴(kuò)展除外),這就意味著PHP本身...
Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

User voice input is captured and sent to the PHP backend through the MediaRecorder API of the front-end JavaScript; 2. PHP saves the audio as a temporary file and calls STTAPI (such as Google or Baidu voice recognition) to convert it into text; 3. PHP sends the text to an AI service (such as OpenAIGPT) to obtain intelligent reply; 4. PHP then calls TTSAPI (such as Baidu or Google voice synthesis) to convert the reply to a voice file; 5. PHP streams the voice file back to the front-end to play, completing interaction. The entire process is dominated by PHP to ensure seamless connection between all links.

The core method of building social sharing functions in PHP is to dynamically generate sharing links that meet the requirements of each platform. 1. First get the current page or specified URL and article information; 2. Use urlencode to encode the parameters; 3. Splice and generate sharing links according to the protocols of each platform; 4. Display links on the front end for users to click and share; 5. Dynamically generate OG tags on the page to optimize sharing content display; 6. Be sure to escape user input to prevent XSS attacks. This method does not require complex authentication, has low maintenance costs, and is suitable for most content sharing needs.

To realize text error correction and syntax optimization with AI, you need to follow the following steps: 1. Select a suitable AI model or API, such as Baidu, Tencent API or open source NLP library; 2. Call the API through PHP's curl or Guzzle and process the return results; 3. Display error correction information in the application and allow users to choose whether to adopt it; 4. Use php-l and PHP_CodeSniffer for syntax detection and code optimization; 5. Continuously collect feedback and update the model or rules to improve the effect. When choosing AIAPI, focus on evaluating accuracy, response speed, price and support for PHP. Code optimization should follow PSR specifications, use cache reasonably, avoid circular queries, review code regularly, and use X

1. Maximizing the commercial value of the comment system requires combining native advertising precise delivery, user paid value-added services (such as uploading pictures, top-up comments), influence incentive mechanism based on comment quality, and compliance anonymous data insight monetization; 2. The audit strategy should adopt a combination of pre-audit dynamic keyword filtering and user reporting mechanisms, supplemented by comment quality rating to achieve content hierarchical exposure; 3. Anti-brushing requires the construction of multi-layer defense: reCAPTCHAv3 sensorless verification, Honeypot honeypot field recognition robot, IP and timestamp frequency limit prevents watering, and content pattern recognition marks suspicious comments, and continuously iterate to deal with attacks.

PHP does not directly perform AI image processing, but integrates through APIs, because it is good at web development rather than computing-intensive tasks. API integration can achieve professional division of labor, reduce costs, and improve efficiency; 2. Integrating key technologies include using Guzzle or cURL to send HTTP requests, JSON data encoding and decoding, API key security authentication, asynchronous queue processing time-consuming tasks, robust error handling and retry mechanism, image storage and display; 3. Common challenges include API cost out of control, uncontrollable generation results, poor user experience, security risks and difficult data management. The response strategies are setting user quotas and caches, providing propt guidance and multi-picture selection, asynchronous notifications and progress prompts, key environment variable storage and content audit, and cloud storage.

PHP ensures inventory deduction atomicity through database transactions and FORUPDATE row locks to prevent high concurrent overselling; 2. Multi-platform inventory consistency depends on centralized management and event-driven synchronization, combining API/Webhook notifications and message queues to ensure reliable data transmission; 3. The alarm mechanism should set low inventory, zero/negative inventory, unsalable sales, replenishment cycles and abnormal fluctuations strategies in different scenarios, and select DingTalk, SMS or Email Responsible Persons according to the urgency, and the alarm information must be complete and clear to achieve business adaptation and rapid response.

PHPisstillrelevantinmodernenterpriseenvironments.1.ModernPHP(7.xand8.x)offersperformancegains,stricttyping,JITcompilation,andmodernsyntax,makingitsuitableforlarge-scaleapplications.2.PHPintegrateseffectivelyinhybridarchitectures,servingasanAPIgateway

Select the appropriate AI voice recognition service and integrate PHPSDK; 2. Use PHP to call ffmpeg to convert recordings into API-required formats (such as wav); 3. Upload files to cloud storage and call API asynchronous recognition; 4. Analyze JSON results and organize text using NLP technology; 5. Generate Word or Markdown documents to complete the automation of meeting records. The entire process needs to ensure data encryption, access control and compliance to ensure privacy and security.
