Home >Backend Development >PHP Tutorial >PHP Master | Better Understanding PHP's Garbage Collection

PHP Master | Better Understanding PHP's Garbage Collection

尊渡假赌尊渡假赌尊渡假赌
尊渡假赌尊渡假赌尊渡假赌Original
2025-02-26 08:33:13197browse

PHP Master | Better Understanding PHP’s Garbage Collection

Time changes, and the terms change accordingly. Today, we might call it "PHP resource recycling" rather than "garbage recycling". This more closely reflects its essence: it is not simply discarding, but repurposing resources that are no longer used. However, it is more common to follow the history of "garbage recycling".

Core points:

  • PHP's garbage collection mechanism is divided into three levels: scope end, reference counting and formal garbage collection. At the end of the scope, resources in a function, script, or session are cleared. Reference count tracks the number of entities using a variable. When the count is zero, the variable is destroyed. The formal garbage collection mechanism introduced in PHP 5.3 deals with cases where reference counts are non-zero but can be further decreasing.
  • PHP's garbage collection mechanism is always enabled, but can be controlled manually. It can be disabled in the php.ini file or in the script using the gc_enable() and gc_disable() functions. The gc_collect_cycles() function allows manual garbage collection to be started, and the root buffer size can be modified in the PHP source code.
  • While garbage collection helps manage memory allocation and prevent memory leaks, its resource-intensive properties can also affect performance. Therefore, it should be used strategically, especially in long-running scripts or never-ending scripts, where garbage collection is crucial to preventing memory leaks.
  • Good programming practices help optimize garbage collection. This includes minimizing or eliminating global variables, binding variables to scopes, and paying attention to the situations where array nesting or object references objects, as these situations can lead to memory leaks and are also the main goal of formal garbage collection mechanisms.

Program generated garbage

Program uses resources, sometimes small resources, sometimes large resources. For example, data fields. A program may define a data field (such as a serial number) and use it in the program. Once defined, this data field will take up memory space, possibly only a few bytes, but still space. Since each machine or programming environment has limited available space, the remaining space will reduce the amount of space occupied by this field. When the program ends, the program and any space it consumes will disappear and the total available space will be restored to its maximum size. But what happens if the program never ends? I've written some of these programs before. They are beautiful masterpieces and I am always happy whenever others in the workshop notice that I have created one. Nothing shows your abilities better than having a large IBM computer down on your own, and in the surrounding compartments, one person after another shouts, “Hey, is there something wrong with the system?” The trick is the second Or a third join to divert attention from you. But some programs are even designed to run forever, such as daemons and other such programs. As they run, the amount of garbage they generate may continue to grow. If the locked resources are large, it will have a real negative impact on the system. Therefore, each language must have a way to clear orphan resources, make them available to other users, and ensure that the total amount of available system space remains the same. Fortunately, PHP uses a three-layer method for garbage removal.

First layer—end of scope

First of all, like most languages, whenever the scope ends, everything within that scope is destroyed and any allocated resources are freed. Scopes can cover functions, scripts, sessions, etc. When the scope ends, everything it holds ends with it. Of course, you can free up resources at any time using the unset() function. This is one of the reasons functions and methods are so important because they set up scopes, specify when a particular memory usage begins and ends, and limits how long things exist. They should be used wherever possible, not global entities.

Second layer—citation count

Secondly, like most scripting languages, PHP uses a technique called reference counting to track how many entities are using a given variable. When creating a variable in a PHP script, PHP creates a small "container" named zval that consists of the value assigned to the variable plus two other pieces of information: is_ref and refcount. The zval container is stored in a table, and each scope (scripts, functions, methods, etc.) has a table. is_ref is a simple true/false value indicating whether the variable is part of the reference set, thus helping PHP determine whether it is a simple variable or a reference. refcount is more interesting because it holds a numeric value indicating how many different variables are using this value. That is, if you define the variable $dave = 6, refcount will be set to 1. If I say $programmer = $dave, refcount will be incremented to 2. PHP knows not to create a second zval for value 6; it just updates the counter on the existing value container. This refcount will decrement when the program ends, either when we leave the scope of the function, or when using unset() . When refcount reaches zero, zval will be destroyed and any memory it holds is now freed. Of course, this is a simple example of a simple variable. When you talk about an array or object, the situation is much more complicated because multiple zrefs will be created for multiple values ​​of elements in the array, but the basic processing is the same. However, if we use arrays in another array, which happens frequently in more complex PHP scripts, problems arise. In this case, when the original array value is set, the refcount of the array value is set to 1, and then when the array is associated with another array, the refcount is incremented to 2. If the usage range of the second array ends, refcount is decremented by 1. We are now in a situation where the value itself is no longer associated with anything, but the refcount of the container (zval) that represents it is still greater than zero. The end result is that the storage represented by the original array will not be freed and that amount of memory is now unavailable for anything. Often, we think this lost storage is small, but it is not usually the case. Arrays can be very large things these days, and it is especially problematic if the script that happens is a daemon or other function that runs almost continuously. In this case, the resulting "memory leak" can have catastrophic consequences for performance and even the server's operational capabilities.

The third floor—formal garbage recycling

Obviously, the clearing based on reference count has its limitations, but luckily, PHP 5.3 provides another option to help with this situation. The specific case we want the garbage collection cycle to solve is the case where zval is decreasing but is still non-zero. Basically, loop to see which values ​​can be further decremented and then release values ​​with zero. What actually happens is that PHP tracks all root containers (zval). This is done regardless of whether garbage collection is on or not (because it just needs to do this without asking if garbage collection is on or not, etc.). This root buffer can hold up to 10,000 roots (fixed size, but this can be changed). When it fills up, the garbage collection mechanism will start and begin analyzing this buffer. The first thing the GC routine does is to iterate through the root buffer and decrement all zval counts by 1. When doing this, it marks each tag with a small tag like a check mark so that it decrements the root only once. It then iterates over and marks (this time using a small wavy line) all the zvals whose reduced count is zero. Values ​​that are non-zero will increment so that they return to their original values. Finally, it will scroll again, clear non-zero zval from the buffer, and free the store with the value of zero refcount. Garbage collection is always enabled in PHP, but you can turn it off using the directive zend.enable_gc in the php.ini file. Alternatively, you can do this in the script by calling the gc_enable() and gc_disable() functions. As mentioned above, if garbage collection is enabled, it runs when the root is full, but you can override this setting and run the collection using the gc_collect_cycles() function when you see fit. And, you can modify the size of the root buffer using the gc_root_buffer_max_entries value in zend/zend_gc.c in PHP source code. All in all, this allows you to control whether and when and where the GC runs, which is a good thing because it is a bit resource-intensive and therefore may not be the kind of thing you run at will.

When to use it

Since garbage collection can affect performance, it's worth taking the time to determine when you should use it. First, remember that unless you run it publicly (using the gc_collect_cycles() function), formal garbage collection does not happen before the root table (10,000 entries) fills up, and because this table is at the scope level, for small This won't happen with functions. Should you use it on small scripts? It's up to you. It's hard to say that running operations like garbage collection is a bad thing, but if you have small, fast-running scripts that start and end and disappear, there may not be much reward. However, if your server runs many small scripts that remain persistent, it may be worth the effort. The only way to really know is to set a benchmark for your application and view it. Of course, if you have long-running scripts, especially those that never end, then garbage collection is crucial if you want to prevent the kind of memory leaks we discussed above. Perhaps most importantly, we should always try to follow good programming guides so that we minimize or eliminate global variables and bind our variables to scope so that even if we have long running scripts, we This memory can be freed at the end of the function, not at the end of the script. Also be aware of when an array or object reference object is used in an array, as this situation can lead to memory leaks and is the real goal of the formal garbage collection process.

Pictures from Fotolia

PHP Garbage Recycling FAQ (FAQ)

(The FAQ part is omitted here because the article is too long and does not match the pseudo-original goal. The content of the FAQ part is highly coincidental with the original text, pseudo-original is difficult, and the original meaning may be changed after modification.)

The above is the detailed content of PHP Master | Better Understanding PHP's Garbage Collection. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn