0内存管理改进,获得php代码使用占用内存的情况

测试php脚本(mem.php),int memory

php5.2.0的内存管理做了较大的改进,某些情况下内存不能释放的问题不存在了。
测试php脚本(mem.php),我用echo N>>和sleep来控制脚本在某个阶段暂停以便检测状态。

 memory_0内存管理改进,获得php代码使用占用内存的情况。get_usage()官方语法

复制代码 代码如下:

一,函数原型
int memory_0内存管理改进,获得php代码使用占用内存的情况。get_usage ([0内存管理改进,获得php代码使用占用内存的情况。 bool $real_usage = false ] )

<?php 
echo ‘1>>’; 
sleep(5); 

二,版本兼容
0内存管理改进,获得php代码使用占用内存的情况。PHP 4 >= 4.3.2, PHP 5

$o = array(); 
for ($i=0;$i<=100000;$i++) { 
    $o[]=’aaaaaaaaaaaaaaaaaaaaa’; 

echo ‘2>>’; 
sleep(5); 

三,基础用法与实例

unset($o); 
echo ‘3>>’; 
0内存管理改进,获得php代码使用占用内存的情况。while (true) { 
    echo ‘..’; 
    sleep(10); 

?> 

我们可以直接使用 PHP函数 memory_get_0内存管理改进,获得php代码使用占用内存的情况。usage() 查看系统分配给当前 PHP
脚本执行占用的内存多少。
 

监测内存使用情况的bash script(注意:里面的”mem”是取自上面的php脚本名):

 代码如下

while true;do clear;ps au|grep -v “\(vi\|grep\)”|grep “\(mem\|RSS\)”;sleep 2;done;
以下是$/usr/local/bin/php mem.php这个进程在三种状态(数组创建前,数组创建后,数组销毁后)下,用5.1.6和5.2.0的PHP(我使用了一样的configure参数)测试的RSS(内存使用值,单位KB)结果。

<?php
echo memory_get_0内存管理改进,获得php代码使用占用内存的情况。usage(), ‘<br />’;  // 79248
$tmp = str_0内存管理改进,获得php代码使用占用内存的情况。repeat(”, 4000);  // 135408
echo memory_get_usage(), ‘<br />’;
0内存管理改进,获得php代码使用占用内存的情况。unset($tmp);
echo memory_0内存管理改进,获得php代码使用占用内存的情况。get_usage();  // 79248
?> 

php5.1.6:
3164
18076
17572

程序输出的数字单位为 byte(s),也就是当时 PHP 脚本使用的内存(不含
memory_get_usage() 函数本身占用的内存)。

PHP5.2.0:
4088
14400
4424
大家可以看到5.1.6这个版本,unset数组之后,内存并没有从进程里释放出来,虽然它是可以继续被这个php进程再利用,但是却无法被系统的其他进程所使用。而5.2.0则真正释放出了内存。

由上面的例子可以看出,要想减少内存的占用,可以使用 PHP unset()
函数把不再需要使用的变量删除。类似的还有:PHP mysql_free_result()
函数,可以清空不再需要的查询数据库得到的结果集,这样也能得到更多可用内存。

大家可能还注意到,在最开始,5.2.0的内存使用比5.1.6多了几个kb,这是由于5.2.0增加了一些新的东西,这个是很正常的。

PHP memory_get_usage()
函数还可以有个参数,$real_usage,其值为布尔值。默认为
FALSE,表示得到的内存使用量不包括该函数(PHP
内存管理器)占用的内存;当设置为 TRUE 时,得到的内存为不包括该函数(PHP
内存管理器)占用的内存。

另外php5.2.0的内存分配也进行了大的改进,官方的说法是对memory_limit的检测由每次呼叫emalloc()的时候进行改为直接检测从系统请求的内存数据块(blocks)。需要更进一步了解的朋友可以自己去研究代码。而由于内存分配的实现的更改,内存控制可以更精确地被控制在memory_limit之下,也就是说以前php代码里,如果有超过了memory_limit的内存使用而没有出错的,在php5.2.0里可能会报错。为了平衡这次改进,PHP5.2.0的默认的memory_limit由以前的8MB改为了16MB.搜索源代码可以看到这个修改(find . -name \*c -type f |xargs cat |grep memory_limit)。 

格式化 memory_get_usage()
结果以 KB 为单位输出

 代码如下

<?php  

 function convert($size){  

    $unit=array(‘b’,’kb’,’mb’,’gb’,’tb’,’pb’); 

     return @round($size/pow(1024,($i=floor(log($size,1024)))),2).’
‘.$unit[$i]; 

 } 

echo convert(memory_get_usage(true)); 

 ?>

自定义函数获取数组或变量值大小

 

 代码如下

<?php
function array_size($arr){
 ob_start();
 print_r($arr);
 $mem=ob_get_contents();
 ob_end_clean();
 $mem=preg_replace(“/n +/”,””,$mem);
 $mem=strlen($mem);
 return $mem;
}
$memEstimate=array_size($GLOBALS);
?>

所以在实际编程中,可以用 memory_get_usage()
函数比较各个方法占用内存的高低,来选择使用哪种占用内存小的方法。
 

附带个使用函数:

 

 代码如下

<?php
if (!function_exists(‘memory_get_usage’)) {
 function memory_get_usage() {
     $pid = getmypid();
      if (IS_WIN) {
         exec(‘tasklist /FI “PID eq ‘ . $pid . ‘” /FO LIST’, $output);
         return preg_replace(‘/[^0-9]/’, ”, $output[5]) * 1024;
      } else {
         exec(“ps -eo%mem,rss,pid
| grep $pid”, $output);
         $output = explode(”
“, $output[0]);
         return $output[1] * 1024;
      }
    }
}
?> 

再来个函数使用例子:
 

 

 代码如下

<?php 
//memory_get_usage(); 
 
$m1 = memory_get_usage(); 
echo ‘<br /> m1:’,$m1;  // m1:80160
 
$a = ‘hello’; 
$b =  str_repeat($a,1000); 
 
$m2 = memory_get_usage(); 
echo ‘<br /> m2:’,$m2;  // m2:85624

unset($b); 
 
$m3 = memory_get_usage(); 
echo ‘<br /> m3:’,$m3;  // m3:80600
?>

所以在实际编程中,可以用PHP
memory_get_usage()比较各个方法占用内存的高低,来选择使用哪种占用内存小的方法。