/* Link from: http://www.ibm.com/developerworks/cn/opensource/os-php-v521/
* Author profile: Tracy Peterson (tracy@tracypeterson.com), freelance writer, consultant. From
* Since 1997, Tracy Peterson has been an IT project manager and web developer.
* Head of Microsoft's MSN Search computing program. He is currently working in San Francisco.
* Finishing staff: Luo Dong ld5202@126.com
*/
PHP v5.2: Start
PHP V5.2 was released in November 2006, which includes many new features and error fixes. It abolished version 5.1 and is recommended to all PHP V5 users for upgrade. My favorite lab environment-Windows, Apache, MySQL, PHP (WAMP)-has been introduced into the new software package V5.2 (see references ). You will find the applications where PHP V5.2, MySQL, and Apache are installed on Windows XP or 2003 computers. You can install it easily. It has many minor management advantages, and I sincerely recommend it.
Although this is the simplest Software Package for Windows users, you need to add the following code When configuring PHP on Linux: -- memory-limit-enabled (except for any other options on your server ). However, in Windows, a function is provided to solve this problem.
PHP V5.2 has many improvements and a crucial area is memory management. Accurately quoted from README. ZEND_MM: "The goal of the new Memory Manager (PHP5.2 and later) is to reduce memory allocation overhead and accelerate memory management ."
The following are some key content in the V5.2 release notes:
Unnecessary -- disable-zend-memory-manager configuration options are deleted.
The -- enable-malloc-mm configuration option is added. During build debugging, this configuration option is enabled by default to allow internal and external memory debugging programs.
Allow ZEND_MM_MEM_TYPE and ZEND_MM_SEG_SIZE environment variables to be used to adjust the Memory Manager
To understand the meaning of these new features, we need to study the art of Memory Management in depth and consider why allocating overhead and running speed are a big problem.
Why memory management?
One of the fastest developing technologies in computing is memory and data storage, which are driven by the continuous demand for increasing speed and storage size. Early computers used cards as memory and switched to chip technology. Can you imagine that a computer with only 1 kb ram memory works? Many early computer programmers have used it. These pioneers soon realized that to work under technical restrictions, they would have to carefully use trivial commands to avoid System overload.
As a PHP developer, our environment is easier to code than our colleagues who use C ++ or other more rigorous language encoding. In our world, we don't have to worry about how to handle system memory, because PHP will handle this problem for us. However, in other programming fields, responsible coding personnel will use various functions to ensure that the executed commands do not overwrite other program data-thus, undermining the running of the program.
Memory Management is usually handled by self-coding personnel requests to allocate and release memory blocks. The allocation block can save any type of data, and this process will separate a certain amount of memory for the data, and provide the access method for the application when the operation needs to access the data. People expect the program to release the allocated memory after any operation and allow the system and other programmers to use the memory. If the program does not release the memory back to the system, it is called Memory leakage.
Leakage is a common problem in any running program, and is generally acceptable to some extent, especially when we know that the running program will immediately terminate and release all the memory allocated to the program by default.
It is a problem because the program is run and terminated randomly, just like almost all client applications. It is expected that the server application runs uncertain without terminating or restarting, which makes memory management absolutely crucial for server daemon programming. In a program that runs for a long time, even if a small leak occurs, the system will eventually become weak because the memory block has been used and will never be released.
Long-term considerations
Like writing in any language, permanent server daemon written in PHP has many possibilities. But when we start using PHP for these purposes, we must also consider memory usage.
Scripts that parse a large amount of data or may hide infinite loops tend to consume a large amount of memory. Obviously, once the memory is exhausted, the server performance will be reduced. Therefore, we must pay attention to the memory usage when executing the script. Although we can simply observe the memory usage by enabling the system monitor, it does not tell us anything more useful than the overall system memory status. Sometimes we don't just need to help with troubleshooting or optimization, but sometimes we just need more details.
One way to get the transparency of script execution content is to use an internal or external debugger. The internal debugger is the same process as the execution script. An independent process is an external debugger from the operating system perspective. Memory analysis using the debugger is similar to any situation, but different methods are used to access the memory. The internal debugger has direct access to the memory space of the running process, and the external debugger accesses the memory through sockets.
There are many methods and available debugging servers (external) and Libraries (internal) that can be used for auxiliary development. To prepare PHP installation for debugging, you can use the new -- enable-malloc-mm, which is enabled by default in the debug build. This allows the environment variable use_zend_alloc to be used to allow malloc or emalloc memory allocation during runtime. The use of malloc-type memory allocation will allow the external debugger to observe the memory usage, and the emalloc allocation will use the Zend Memory Manager abstraction, requiring internal debugging.
Memory management functions in PHP
In addition to making the memory manager more flexible and transparent, PHP v5.2 also provides a new parameter for memory_get_usage () and memory_get_peak_usage (), which allow you to view memory usage. The new Boolean value mentioned in the description is real_size. By calling the memory_get_usage ($ real); ($ real = true) function, the result is the actual memory size allocated by the system during the call, including the Memory Manager overhead. If no tag group is used, the returned data will only include the memory used in the running script, minus the Memory Manager overhead.
The difference between memory_get_usage () and memory_get_peak_usage () is that the latter returns the maximum memory size of the running process called so far, while the former returns only the usage during execution.
For memory_get_usage (), php.net provides code snippets in Listing 1.
Listing 1. memory_get_usage () Example
<? PHP
// This is only an example, the numbers below will
// Differ depending on your system
Echo memory_get_usage (). "\ n"; // 36640
$ A = str_repeat ("hello", 4242 );
Echo memory_get_usage (). "\ n"; // 57960
Unset ($ );
Echo memory_get_usage (). "\ n"; // 36744
?>
In this simple example, we first turn to the result of calling memory_get_usage () directly. The code comment may show 36640 bytes of common results in the author's system. Then we use 4,242 "hello" copies to load $ A and run the function again. Figure 1 shows the output of this simple application.
Figure 1. sample output of memory_get_usage ()
There is no memory_get_peak_usage () example, because the two are very similar and the syntax is the same. However, the sample code in Listing 1 has only one result, that is, the maximum memory usage at that time. Let's take a look at listing 2.
Listing 2. memory_get_peak_usage () Example
<? PHP
// This is only an example, the numbers below will
// Differ depending on your system
Echo memory_get_peak_usage (). "\ n"; // 36640
$ A = str_repeat ("hello", 4242 );
Echo memory_get_peak_usage (). "\ n"; // 57960
Unset ($ );
Echo memory_get_peak_usage (). "\ n"; // 36744
?>
The code in Listing 2 is the same as Figure 1, but memory_get_usage () has been replaced with memory_get_peak_usage (). The output won't be changed much before we fill $ A with 4242 "hello" replicas. Memory jumps to 57960, indicating the peak value so far. When you check the peak memory usage, the maximum value is obtained so far, so all further calls will get 57960, until we process more operations than the memory used to process $ A (see figure 2 ).
Figure 2. sample output of memory_get_peak_usage ()
Restrict memory usage
One way to ensure that the servers hosting applications are not overloaded is to limit the amount of memory used by any scripts executed by PHP. This is not the operation we should perform, but because PHP is a loose language and parsed at runtime, therefore, we sometimes get a script that is poorly written after being released to the production application. These scripts may execute loops or open a long file list. If you forget to close the current file before opening a new file. In either case, poorly written scripts may end up consuming a lot of memory before you know it.
In PHP. INI, you can use the preparation parameter memory_limit to specify the maximum memory usage that any script can run in the system. This is not a specific change to V5.2, but the memory manager and any discussions on its use are worth viewing this feature at least once. It also carefully guides me through the last few new features of the Memory Manager: environment variables.
Adjust Memory Manager
Finally, how can we program without being a perfectionist but completely serving our purposes? The new environment variables ZEND_MM_MEM_TYPE and ZEND_MM_SEG_SIZE can meet your needs.
When the Memory Manager allocates large memory blocks, it installs the pre-size operations listed in the ZEND_MM_SEG_SIZE variable. The default partition size of these memory blocks is 256 KB, but you can adjust the partition size to meet special requirements. For example, if you notice that the operation in the most common script causes a large amount of memory waste, you can adjust this size to a value closer to match the script requirement, the amount of allocated memory is reduced, but the remaining amount of memory is still zero. Under the correct conditions, such careful Configuration Adjustment may cause a huge difference.
Retrieve memory usage in Windows
If you have pre-built PHP windows binary code without using the -- enable-memory-limit option during build, you need to browse this part before continuing. For Linux, use the -- enable-memory-limit option to build PHP during PHP build configuration.
To use Windows binary code to retrieve memory usage, create the following functions.
Listing 3. Getting memory usage in Windows
<? PHP
Function memory_get_usage (){
$ Output = array ();
Exec ('tasklist/fi "pid eq '. getmypid ().'"/FO list', $ output );
Return preg_replace ('/[^ 0-9]/', ', $ output [5]) * 1024;
}
?>
Save the result to a file named function. php. Now you can only include this file in the script that requires it.
Practice
Let's take a look at the benefits of using the actual examples of these settings. You may wonder why the memory is not allocated properly at the end of the script many times. The reason is that some functions cause memory leakage, especially when only built-in PHP functions are used. Here, you will learn how to discover such problems. To start the Memory Leak search, you will create a MySQL database, as shown in Listing 4.
Listing 4. Creating a Test Database
Mysql> create database memory_test;
Mysql> use memory_test;
Mysql> create table leak_test
(Id int not null primary key auto_increment,
Data varchar (255) not null default '');
Mysql> insert into leak_test (data) values ("data1"), ("data 2 "),
("Data 3"), ("data 4"), ("data 5"), ("data6"), ("data 7 "),
("Data 8"), ("Data 9"), ("Data 10 ");
This creates a simple table with the ID field and data field.
In the next list, imagine that our tough programmer is executing some MySQL functions, especially using mysql_query () to apply the results to variables. When doing so, he will notice that some memory will not be released even if mysql_free_result () is called, resulting in memory usage increasing with the Apache process (see listing 5 ).
Listing 5. Examples of Memory leakage detection
For ($ x = 0; $ x <300; $ X ++ ){
$ Db = mysql_connect ("localhost", "root", "test ");
Mysql_select_db ("test ");
$ SQL = "Select data from test ";
$ Result = mysql_query ($ SQL); // The operation suspected of leaking
Mysql_free_result ($ result );
Mysql_close ($ dB );
}
Listing 5 is a simple MySQL database operation that can be used anywhere. When running the script, we noticed some strange behaviors related to memory usage and need to check them out. To use the memory management function so that we can check the location where an error occurs, we will use the following code.
Listing 6. Examples of calibration lookup errors
<? PHP
If (! Function_exists ('memory _ get_usage ')){
Include ('function. php ');
}
Echo "at the start we're using (in bytes ):",
Memory_get_usage (), "\ n <br> ";
$ Db = mysql_connect ("localhost", "user", "password ");
Mysql_select_db ("memory_test ");
Echo "After connecting, we're using (in bytes ):",
Memory_get_usage (), "\ n <br> ";
For ($ x = 0; $ x <10; $ x ++ ){
$ SQL =
"SELECT data FROM leak_test WHERE id = '". $ x ."'";
$ Result = mysql_query ($ SQL); // The operation
// Suspected of leaking.
Echo "After query # $ x, we're using (in bytes ):",
Memory_get_usage (), "\ n <br> ";
Mysql_free_result ($ result );
Echo "After freeing result $ x, we're using (in bytes ):",
Memory_get_usage (), "\ n <br> ";
}
Mysql_close ($ db );
Echo "After closing the connection, we're using (in bytes ):",
Memory_get_usage (), "\ n <br> ";
Echo "Peak memory usage for the script (in bytes ):".
Memory_get_peak_usage ();
?>
Note: Check the current memory usage according to the defined interval. In the following output, we show that our script has been allocating memory for the function, and the memory should not be released at the time of release, so as to provide a practical test of Memory leakage, you can see how memory usage increases during each call.
Listing 7. Test Script output
At the start we're using (in bytes): 63216
After connecting, we're using (in bytes): 64436
After query #0, we're using (in bytes): 64760
After freeing result 0, we're using (in bytes): 64828
After query #1, we're using (in bytes): 65004
After freeing result 1, we're using (in bytes): 65080
After query #2, we're using (in bytes): 65160
After freeing result 2, we're using (in bytes): 65204
After query #3, we're using (in bytes): 65284
After freeing result 3, we're using (in bytes): 65328
After query #4, we're using (in bytes): 65408
After freeing result 4, we're using (in bytes): 65452
After query #5, we're using (in bytes): 65532
After freeing result 5, we're using (in bytes): 65576
After query #6, we're using (in bytes): 65656
After freeing result 6, we're using (in bytes): 65700
After query #7, we're using (in bytes): 65780
After freeing result 7, we're using (in bytes): 65824
After query #8, we're using (in bytes): 65904
After freeing result 8, we're using (in bytes): 65948
After query #9, we're using (in bytes): 66028
After freeing result 9, we're using (in bytes): 66072
After closing the connection, we're using (in bytes): 65108
Peak memory usage for the script (in bytes): 88748
We discovered some suspicious operations when executing the script, and adjusted the script to provide us with some understandable feedback. We ran the script again and used memory_get_usage () during each iteration to view the changes in memory usage. Based on the increase in the allocated memory value, it implies that we have used scripts to establish a vulnerability somewhere. Because the mysql_free_result () function does not release memory, we can think that mysql_query () does not properly allocate memory.
Conclusion
PHP V5.2 includes some excellent new tools to help you better understand the memory allocation of the script system, and re-control the precise adjustment of memory management. When it is used effectively, the new memory management tool will support debugging and regain some system resources.