一.内存溢出解决方案

在做数据统计分析时,经常会遇到大数组,可能会发生内存溢出,这里分享一下我的解决方案。还是用例子来说明这个问题,如下:

假定日志中存放的记录数为500000条,那么解决方案如下:

ini_set(‘memory_limit’,’64M’); //重置php可以使用的内存大小为64M,一般在远程主机上是不能修改php.ini文件的,只能通过程序设置。注:在safe_mode(安全模式)下,ini_set失效

set_time_limit(600);//设置超时限制为6分钟

$farr = $Uarr = $Marr = $IParr = $data = $_sub = array();

$spt = ”$@#!$”;

$root = ”/Data/webapps/VisitLog”;

$path = $dpath = $fpath = NULL;

$path = $root.”/”.date(“Y-m”,$timestamp);

$dpath = $path.”/”.date(“m-d”,$timestamp);

for($j=0;$j<24;$j++){

$v = ($j < 10) ? ”0″.$j : $j;

$gpath = $dpath.”/”.$v.”.php”;

if(!file_exists($gpath)){

continue;

} else {

$arr = file($gpath);////将文件读入数组中

array_shift($arr);//移出第一个单元-》<?php exit;?>

$farr = array_merge($farr,$arr);

unset($arr);

}

}

if(empty($this->farr)){

echo ”<p><center>没有相关记录!</center></p>”;

exit;

}

while(!empty($farr)){

$_sub = array_splice($farr, 0, 10000); //每次取出$farr中1000个

for($i=0,$scount=count($_sub);$i<$scount;$i++){

$arr = explode($spt,$_sub[$i]);

$Uarr[] = $arr[1]; //vurl

$Marr[] = $arr[2]; //vmark

$IParr[] = $arr[3].” |$nbsp;”.$arr[1]; //IP

}

unset($_sub);//用完及时销毁

}

unset($farr);

这里,不难看出,一方面,我们要增加PHP可用内存大小,另一方面,只要我们想办法对数组进行分批处理,分而治之,将用过的变量及时销毁(unset),一般是不会出现溢出问题的。

另外,为了节省PHP程序内存损耗,我们应当尽可能减少静态变量的使用,在需要数据重用时,可以考虑使用引用(&)。再一点就是:数据库操作完成后,要马上关闭连接;一个对象使用完,要及时调用析构函数(__destruct())。

二.unset销毁变量并释放内存问题

PHP的unset()函数用来清除、销毁变量,不用的变量,我们可以用unset()将它销毁。但是某些时候,用unset()却无法达到销毁变 量占用的内存!我们先看一个例子:

<?php
$s=str_repeat('1',255); //产生由255个1组成的字符串
$m=memory_get_usage(); //获取当前占用内存
unset($s);
$mm=memory_get_usage(); //unset()后再查看当前占用内存
echo $m-$mm;
?>

最后输出unset()之前占用内存减去unset()之后占用内存,如果是正数,那么说明unset($s)已经将$s从内存中销毁(或者
说,unset()之后内存占用减少了),可是我在PHP5和windows平台下,得到的结果是:0。这是否可以说明,unset($s)并没有起
到销毁变量$s所占用内存的作用呢?我们再作下面的例子:

<?php
$s=str_repeat('1',256); //产生由256个1组成的字符串
$m=memory_get_usage(); //获取当前占用内存
unset($s);
$mm=memory_get_usage(); //unset()后再查看当前占用内存
echo $m-$mm;
?>

这个例子,和上面的例子几乎相同,唯一的不同是,$s由256个1组成,即比第一个例子多了一个1,得到结果是:272。这是否可以说 明,unset($s)已经将$s所占用的内存销毁了?
通过上面两个例子,我们可以得出以下结论:
结论一、unset()函数只能在变量值占用内存空间超过256字节时才会释放内存空间。

那么是不是只要变量值超过256,使用unset就可以释放内存空间呢?我们再通过一个例子来测试一下:

<?php
$s=str_repeat('1',256); //这和第二个例子完全相同
$p=&$s;
$m=memory_get_usage();
unset($s); //销毁$s
$mm=memory_get_usage();
echo $p.'<br />';
echo $m-$mm;
?>

刷新页面,我们看到第一行有256个1,第二行是0,按理说我们已经销毁了$s,而$p只是引用$s的变量,应该是没有内容了,另 外,unset($s)前后内存占用没变化!现在我们再做以下的例子:

<?php
$s=str_repeat('1',256); //这和第二个例子完全相同
$p=&$s;
$m=memory_get_usage();
$s=null; //设置$s为null
$mm=memory_get_usage();
echo $p.'<br />';
echo $m-$mm;
?>

现在刷新页面,我们看到,输出$p已经是没有内容了,unset()前后内存占用量之差是272,即已经清除了变量占用的内存。本例中的$s=null也 可以换成unset(),如下:

<?php
$s=str_repeat('1',256); //这和第二个例子完全相同
$p=&$s;
$m=memory_get_usage();
unset($s); //销毁$s
unset($p);
$mm=memory_get_usage();
echo $p.'<br />';
echo $m-$mm;
?>

我们将$s和$p都使用unset()销毁,这时再看内存占用量之差也是272,说明这样也可以释放内存。那么,我们可以得到另外一条结论:
结论二、只有当指向该变量的所有变量(如引用变量)都被销毁后,才会释放内存。

PHP内存溢出解决方案的更多相关文章

  1. 应用jacob组件造成的内存溢出解决方案(java.lang.OutOfMemoryError: Java heap space)

    http://www.educity.cn/wenda/351088.html 使用jacob组件造成的内存溢出解决方案(java.lang.OutOfMemoryError: Java heap s ...

  2. vue2打包时内存溢出解决方案

    vue项目完成时,若项目过大,就会出现内存溢出的问题,导致vue打包不成功 错误截图 解决方案 在依赖package.json中修改build为 "build":"nod ...

  3. JVM内存监视手段和内存溢出解决方案

    引言 本文仅关注一些常见的虚拟机内存监视手段,以及JVM运行时数据区各个部分内存溢出的发生和对应的解决方案,总体来说属于概括性总结,涉及相对不是很深入,目的是让自己和其它初学者有一个框架性.概念性的了 ...

  4. 牛客网Java刷题知识点之内存溢出和内存泄漏的概念、区别、内存泄露产生原因、内存溢出产生原因、内存泄露解决方案、内存溢出解决方案

    不多说,直接上干货! 福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号:   大数据躺过的坑      Java从入门到架构师      人工智能躺过的坑          ...

  5. Jmeter报内存溢出解决方案

    描述:wimdows环境,做上传图片接口测试,涉及图片合成和上传,图片采用base64编码.每1s启动200线程的时候,Jmeter报内存溢出错误. 解决方案: 1.修改jmeter.bat: set ...

  6. Android内存溢出解决方案(OOM)

    众所周知,每个Android应用程序在运行时都有一定的内存限制,限制大小一般为16MB或24MB(视平台而定).因此在开发应用时需要特别关注自身的内存使用量,而一般最耗内存量的资源,一般是图片.音频文 ...

  7. Android 内存溢出解决方案(OOM) 整理总结

    在最近做的工程中发现加载的图片太多或图片过大时经常出现OOM问题,找网上资料也提供了很多方法,但自己感觉有点乱,特此,今天在不同型号的三款安卓手机上做了测试,因为有效果也有结果,今天小马就做个详细的总 ...

  8. Android 内存溢出解决方案(OOM) 整理总结<转>

    在最近做的工程中发现加载的图片太多或图片过大时经常出现OOM问题,找网上资料也提供了很多方法,但自己感觉有点乱,特此,今天在不同型号的三款安卓手机上做了测试,因为有效果也有结果,今天小马就做个详细的总 ...

  9. jenkins 构建部署时tomcat7 内存溢出解决方案

    在使用jenkins构建部署时一直出现tomcat7内存溢出 WARNING: Unexpected node monitoring termination: Clock Difference jav ...

随机推荐

  1. elasticsearch installation guide

    UBUNTU 14.04 LTS 安装 elasticseach同步MYSQL表并实现中文搜索 ==================================================== ...

  2. PCA算法是怎么跟协方差矩阵/特征值/特征向量勾搭起来的?

    PCA, Principle Component Analysis, 主成份分析, 是使用最广泛的降维算法. ...... (关于PCA的算法步骤和应用场景随便一搜就能找到了, 所以这里就不说了. ) ...

  3. quartz启动时间配置

    这些星号由左到右按顺序代表 : * * * * * * * 格式: [秒] [分] [小时] [日] [月] [周] [年] 序号 说明 是否必填 允许填写的值 允许的通配符 1 秒 是 0-59 , ...

  4. Freemarker list标签,list数据判断使用

    <#if listSecMDIF?exists && (listSecMDIF?size>0)> <ul style="float: left;mar ...

  5. Linux下执行.sh文件

    Linux下执行.sh文件有两种情况: 一.直接./加上文件名.sh,如运行hello.sh为./hello.sh[hello.sh必须有x权限] 二.直接sh 加上文件名.sh,如运行hello.s ...

  6. hive 使用笔记(table format;lateral view)

    1. create table 创建一张目标表,指定分隔符和存储格式: create table tmp_2 (resource_id bigint ,v int) ROW FORMAT DELIMI ...

  7. C# 调用api的方法

    问题场景: ASP.NET MVC Web API 定义 Post 方法,HttpClient 使用 JsonConvert.SerializeObject 传参进行调用,比如 Web Api 中定义 ...

  8. DIV横排/竖排滚动(white-space/::-webkit-scrollbar的使用技巧以及display: inline-block的选择)支持手势

    参考微信的京东客户端http://wqs.jd.com/,实现DIV的横排滚动,且支持手势,并且不会出现滚动跳,效果如下: 但是观察其div结构是没有使用任何JS去实现. 一.实现上DIV的横排 观察 ...

  9. Gulp解决发布线上文件(CSS和JS)缓存问题

    Gulp解决发布线上文件(CSS和JS)缓存问题 本文的缘由:目前经常线上发布文件后要不断的刷新页面及过很长时间,页面上的CSS和JS文件才能生效,特别对于目前做微信商城的时候,微信内置的浏览器缓存非 ...

  10. Android数据库升级

    随着Android应用版本的迭代,经常遇到数据库表结构发生改变,或者一些指定的表数据需要更新.这也就引出一个问题Android数据库的更新问题. Android数据库升级分类 Android数据库更新 ...