最近做一个导入大文件,因为涉及到要对文件处理得到需要的结构的数据。
把大量数据保存在数组中。
在处理的过程中,消耗很大内存,不是memory_limit设置问题,我已经设置足够大。
处理过程中自己也有unset掉不要的。但是通过memory_get_usage()输出函数调用前跟调用后的内存对比。
发现函数调用后,内存并没有明显的下降。那些大数组都已经unset掉了。也是一样。
如果导入的文件量不大,不会出现内存溢出的错误提示。但是当文件大到一定程度。就因为执行过程中,
函数调用完,内存还是占用很大。而导致内存溢出。
这个让我有点郁闷了。函数调用完不是都释放了局部变量空间了吗?
是不是什么内存泄露,有人遇到相同问题吗。希望有遇到相同问题的或者有人知道的。一起来讨论下。谢谢。
ps:分数蛮少的,只能这样了。
把大量数据保存在数组中。
在处理的过程中,消耗很大内存,不是memory_limit设置问题,我已经设置足够大。
处理过程中自己也有unset掉不要的。但是通过memory_get_usage()输出函数调用前跟调用后的内存对比。
发现函数调用后,内存并没有明显的下降。那些大数组都已经unset掉了。也是一样。
如果导入的文件量不大,不会出现内存溢出的错误提示。但是当文件大到一定程度。就因为执行过程中,
函数调用完,内存还是占用很大。而导致内存溢出。
这个让我有点郁闷了。函数调用完不是都释放了局部变量空间了吗?
是不是什么内存泄露,有人遇到相同问题吗。希望有遇到相同问题的或者有人知道的。一起来讨论下。谢谢。
ps:分数蛮少的,只能这样了。
解决方案 »
- 在IE下,使用jquery的ajaxForm上传图片以后,返回json数据,被提示下载文件,得不到json数据
- apache php 发送邮件的问题
- 验证码的php页如何和注册页面进行交互,在注册页面显示验证码输入是否正确
- phpMyAdmin无法登录
- 在php里用json?
- 谢谢众家斑竹们,有一个关于php读取文件并分析入库的问题,急呀!!!
- 想找一个PHP做的论坛原代码 什么数据库版本的都行 最好能稳定点的 学习用~ 那位大虾给我介绍个?(给我下载连接也行 告诉我名字也行)谢谢
- 怎么改成英文的..
- 无奈
- 这种入口网页怎么做?
- 求ActiveX的资料教程
- 求助 curl_exec 返回值判断问题
unset是数组
我也知道 函数里unset()全局变量
只是消除函数里面那个临时变量
我都有把全局$GLOBALS 变量给unset
还是如此
以前做的东西没出过类似问题,因为之前没处理过这样大的数据。
现在遇到这样的问题,让我重新思考这个问题。
今天还看了 PHP内存管理的原理了
不知道是否有人也遇到过
global $productIndex;
$unexistPF = array();//用于存放当前项目中没有的excel文件存在的平台
$produceRelFB = array();
$resultMap = null;
$tsResult = null;//测试套件导入结果
$tables = tlObject::getDBTables("platforms");
$pfSql = " select id,name from ".$tables['platforms']." where testproject_id=$tproject_id";
$pfRe = $db->fetchColumnsIntoMap($pfSql,"id","name");
$pfRe = is_null($pfRe) ? array() : $pfRe;
foreach($productIndex as $vKey=>$pItem){
if(!in_array($vKey, $pfRe)){
$unexistPF[] = $vKey;
}
}
// $memory1 = memory_get_usage();
// $fileName = date("md-His");
// $hand = fopen("e:/testcase/".$fileName.".txt","a+");
// $bTime = microtime_float();
$tempTSArray = array();
$createSuc = "创建成功。";
$updateSuc = "更新成功。";
if(is_array($testsuiteArray) && count($testsuiteArray)>0){
foreach($testsuiteArray as $key=>$tsItem){
// $begin = microtime_float();
if ($tsItem['name'] != "")
{
if($tsItem['parentNum']==0){
$parID = $parentID;
}else{
$parID = $tempTSArray[$key]['parentID'];
}
$tsuiteMgr = new testsuite($db);
$info = $tsuiteMgr->get_by_name($tsItem['name'],$parID);
if( is_null($info) )
{
$ret = $tsuiteMgr->create($parID,$tsItem['name'],"",$tsItem['node_order']);
$tsuiteID = $ret['id'];
$tsResult[] = array($tsItem['name'],$createSuc);
}
else
{
$tsuiteID = $info[0]['id'];
$ret = $tsuiteMgr->update($tsuiteID,$tsItem['name'],"",null,$tsItem['node_order']);
$tsResult[] = array($tsItem['name'],$updateSuc);
}
if(is_array($tsItem['children']) && count($tsItem['children'])>0){
foreach($tsItem['children'] as $val){
$tempTSArray[$val]['parentID'] = $tsuiteID;
}
}
}
// $end = microtime_float();
// fwrite($hand, "每条规约用时:".($end-$begin)."\r\n");
}
}
// echo "testsuiteArray前".memory_get_usage()."<br>";
$testsuiteArray = null;
// echo "testsuiteArray后".memory_get_usage()."<br>";
$GLOBALS['testsuiteArray']=null;
// echo "全局testsuiteArray后".memory_get_usage()."<br>";
if(is_array($testcaseArray) && count($testcaseArray)>0){
$tcData = array();
// $begin = microtime_float();
$flag = 0;
foreach ($testcaseArray as $key=>$tsItem){
if($tsItem['parentNum']==0){
$parID = $parentID;
}else{
$parID = $tempTSArray[$key]['parentID'];
}
$tcData[$flag] = array(
"name"=>$tsItem['name'],
"node_order"=>$tsItem['order'],
"parentID"=>$parID
) ;
if(is_array($tsItem['property']) && count($tsItem['property'])>0){
foreach($tsItem['property'] as $pKey=>$val){
$tcData[$flag][$pKey] = $val;
}
}
if(is_array($tsItem['custom_fields']) && count($tsItem['custom_fields'])>0){
foreach($tsItem['custom_fields'] as $cfName=>$cfValue){
$tcData[$flag][customfields][] = array("name"=>$cfName,"value"=>$cfValue);
}
}
if(is_array($tsItem['srs']) && count($tsItem['srs'])>0){
$tcData[$flag]['srs'] = $tsItem['srs'];
}
if(is_array($tsItem['produce']) && count($tsItem['produce'])>0){
$tcData[$flag]['produce'] = $tsItem['produce'];
}
$flag++;
}
// $end = microtime_float();
// fwrite($hand, "循环用例时间:".($end-$begin)."\r\n");
// echo "testcaseArray前".memory_get_usage()."<br>";
$testcaseArray = null;
// echo "testcaseArray后".memory_get_usage()."<br>";
$GLOBALS['testcaseArray']=null;
// echo "全局testcaseArray后".memory_get_usage()."<br>";
$tempTSArray = null;
// echo "tempTSArray后".memory_get_usage()."<br>";
if(is_array($tcData) && count($tcData)>0){
// $begin = microtime_float();
$resultMap = saveImportedTCData1($db,$tcData,$tproject_id,$userID,null,$duplicateLogic,$produceRelFB,$pfRe);
$tcData = null;
// echo "tcData后".memory_get_usage()."<br>";
// $memory2 = memory_get_usage();
// $end = microtime_float();
// fwrite($hand, "保存用例总时间:".($end-$begin)."\r\n");
// fwrite($hand, "总用时:".($end-$bTime)."\r\n");
// fwrite($hand, "内存消耗:".($memory2-$memory1)."\r\n");
}
}
$return = array("resultMap"=>$resultMap,"tsResult"=>$tsResult,"unexistPF"=>$unexistPF,"produceRel"=>$produceRelFB);
return $return;
// return $resultMap;
}
我说明下:$testsuiteArray和$testcaseArray是分析文件,得到的数组。两个数组可能有几十M或者上百M。
现在问题不是想说数组太大,可以采用别的方法目的。问题出在我调用完这个函数,和这个函数里面的saveImportedTCData1函数,调用完saveImportedTCData1 内存也没有明显降低。我试过把所有返回结果跟那些引用的变量都销毁,内存还是占用很大,最终导致溢出了。这样看代码估计很累,谢谢了。
http://www.laruence.com/2011/03/04/1894.html
然后数据库操作,这里涉及的操作很多。
执行完后内存比最开始的大接近1G
这样的结果是不是有什么异常啊。
在处理过程中有把 没必要的数据都unset了。
执行了17W多的数据库操作,和40多秒的数据库执行时间
采用循环操作。
每执行完一个数组的操作内存逐渐增加。
照理说每次循环用到得局部变量都一样。
只有保存数据库操作结果的数组有增加,可是它的增加的量小。
不可能需要那么大的内存。
那这些额外的内存占用从哪里来呢?
直到该函数调用完。这些内存空间都没释放,这是为什么呢?
why?why?why?
遇到这个瓶颈让我很苦恼。
很有成就的大哥大叔们
那多出来的内存怎么来的呢?
HELP。。
我知道你很厉害
之前就在百度找到你的信息
过来帮帮忙吧。
百度上能找到的信息我都找了
php内存分配的原理什么的都看了
有些资料也许没找着
有没有解开疑问的
从事php一年了 之前没有碰到这问题
遇到问题 可以学得更多
可是此时正在烦着呢 睡觉都会想这个问题
有什么关于此类问题的书吗
介绍下。。
mygod
你装xdebug里面有几个功能可以帮助分析内存
还是占用很大$resultMap=saveImportedTCData1($db,$tcData,$tproject_id,$userID,null,$duplicateLogic,$produceRelFB,$pfRe);在这个函数调用前后的内存差别很大。
我把返回结果$resultMap,$tcData,和$produceRelFB等有关联的数据都unset,还是一样。
函数调用完不是释放完它执行时所分配的所有临时空间吗。怎么会这样子。想不通啊。那块内存哪去了?where are you- -
php gc也早就了解了跟java很像的机制。
我现在是觉得不是这些问题
我觉得应该深入php内核 研究下php内存分配机制
我用WinCacheGrind .exe 查看的
还是我没找到- -
另外如果是从数据库中获取数据,记录集资源有没有被释放……
自定义类 还有函数没错
其实最大问题saveImportedTCData1 在这个函数。
我把这个函数产生的所有输出都给释放掉了了。
即使是释放完了 通过meomory_get_usage()输出的内存占用依然是调用这个函数之前内存调用的n倍
大概多了一个数量级。
我看我还是检查下这个函数
话说xdebug 能通过WinCacheGrind 查看内存消耗吗
我没看到有查看内存的 再次向回答人说谢谢
ps:其实如果百度跟谷歌能找到我要的答案我一般不会问。我发现我问的问题大多数没有得到想要答案。能跟大家交流沟通也学习很多。再努力找原因。
加下引用传递再测试一下,可能是因为你函数里有一次变量分离的,而变量本身又很大的缘故。
$resultMap=saveImportedTCData1($db,&$tcData,$tproject_id,$userID,null,$duplicateLogic,&$produceRelFB,$pfRe);
上面那个函数中有行代码 $tcData[$flag][customfields][] = array("name"=>$cfName,"value"=>$cfValue);[customfields]忘了加引号,我记得曾经看手册有提到这个问题,这个会导致效率很低。
因为php要额外很多检查。所以一直都是习惯加引号。可能不小心给忘了。
结果因为大量数据 所以一下子开销差别就出来,我算了下空间开销差了二十倍。时间开销没算。
问题还没解决还在找另一个函数出现的问题。
最终问题得以解决谢谢以上所有朋友