如何在运行长 PHP 脚本时清除内存?尝试取消设置()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10544779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 22:26:00  来源:igfitidea点击:

How can I clear the memory while running a long PHP script? tried unset()

phpmysql

提问by Bob Jones

My script imports an excel file into a product database to update quantities new products etc....

我的脚本将一个 excel 文件导入到产品数据库中以更新新产品的数量等......

I am having memory issue and I have tried raising the memory limit to the max(800MB+). I have tried unsetting the variables in order to release the memory between the loops but I still run out of memory. I have tried setting the timeout to infinite but its definitely a memory issue.

我有内存问题,我尝试将内存限制提高到最大值(800MB+)。我尝试取消设置变量以释放循环之间的内存,但我仍然内存不足。我试过将超时设置为无限,但这绝对是一个内存问题。

Error msg from log file: Fatal error: Allowed memory size of 851443712 bytes exhausted (tried to allocate 71 bytes)

日志文件中的错误消息:致命错误:851443712 字节的允许内存大小已用完(尝试分配 71 字节)

None of the script is contained in a function. If I create the main for loop inside a function and repeatedly call that function will that help garbage collection and clear up memory? Any help or guidance will be appreciated.

任何脚本都不包含在函数中。如果我在一个函数内创建主 for 循环并重复调用该函数是否有助于垃圾收集和清理内存?任何帮助或指导将不胜感激。

Import Script:

导入脚本:

error_reporting( E_ALL & ~E_NOTICE );
ini_set('memory_limit', '812M');
set_time_limit(0);

/* Config Start */
define('BasePath', '/home/xxxxx/public_html');
define('CfgMagentoPath',                    BasePath);
define('CfgCategoryMapDBxls',                   BasePath."/xxxx/Shdddddd.xls");
define('CfgVenderDBxls',                    BasePath."/xxxx/xxxxxx.xls");
define('CfgReportEmail',                    "[email protected]");
/* Config End */

require_once(CfgMagentoPath . '/app/Mage.php');
Mage::app(); 
//$app = Mage::app('default'); 
//Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
require_once(BasePath.'/xxxxx/xxxx/libs/mage.func-inc.php');
require_once(BasePath.'/xxxxx/xxxxx/libs/excel-read.class.php');

//Alert Arrays
$AAnotmapped        = array();
$AAnewproducts  = array();
$AApriceupdated = array();
$AAimgerror         = array();
$PriceErrors        = array();

$SkipCat = false;

//Create Mapped Cats - In Magento

$excel = new ExcelReader(CfgCategoryMapDBxls,"UTF-8");
$CM = $excel->getWorksheetData('Sheet1');
if(!$SkipCat){
    echo "========   Generating Catagory Maps   ===========\n\n";
    CatMap_Create($CM);
    echo "======== ============================== ===========\n\n";
}

//Start Item Read
$excel = new ExcelReader(CfgVenderDBxls,"UTF-8");
$IT = $excel->getWorksheetData('New_DATA');
$ITcnt = 0;
$ITtotal = count($IT);

foreach($IT as $ItemRow){
    $ITcnt++;

    $cSKU                   = $ItemRow['ITEM'];
    $cProductName   = Clean_Data($ItemRow['ALTSHORTDESC']);
    $cCatName           = Clean_Data($ItemRow['CATEGORY']);
    $cManuf                 = Clean_Data($ItemRow['MANUFACTURER']);
    $cShortDesc         = Clean_Data($ItemRow['SHORTDESC']);
    $cLongDesc          = Clean_Data($ItemRow['LONGDESC']);
    $cUPC                       = Prod_GetUPC($ItemRow['UPC'], $ItemRow['ALTUPC']);
    $cStockQty          = $ItemRow['QTY'];
    $cWeight                = Prod_GetWeight($ItemRow['WEIGHT'], $ItemRow['ALTWEIGHT']);
    $cPrice                 = Prod_FigurePrice($ItemRow['COST'], $ItemRow['MSRP'], $ItemRow['MAP']);
    $cCost                  = $ItemRow['COST'];


    //Locate Catagory Map Magento ID
    $mCatId = CatMap_Search($CM, $ItemRow['CATEGORY']);

    //Now Create Product
    if($mCatId > 0 && $cProductName != ""){

        echo date("m.d.y g:i a")."\t($ITcnt / $ITtotal) Working On: " . $cProductName . " - SKU: $cSKU\n";
        $ProdID = Prod_GetIDfromSKU($cSKU);


        if($ProdID > 0){
            if(Prod_Update($ProdID, $cCost, $cStockQty, $cWeight, $cUPC)){
                echo "Updated: $cProductName\n";
                $ITindex++;
            }
        }else{
            Prod_Create($cSKU, $cProductName, $cManuf, $cPrice, $cCost, $cWeight, $cShortDesc, $cLongDesc, $cStockQty, $cUPC, $mCatId);
            echo "Created: $cProductName to Catagory: $mCatId\n";
            echo "$cShortDesc\n\n";
            $ProdID = Prod_GetIDfromSKU($cSKU);
        }


        if($cPrice <= $cCost){
            array_push($PriceErrors, "[$cSKU] $cProductName > Cost: $cCost | Price: $cPrice");  
            echo "Price Lower than Cost : Auto Inactive : Cost: $cCost | Price: $cPrice\n";
        }   

        Prod_AddImg($ProdID, $cSKU);

    }


    unset($ItemRow, $ProdID, $cSKU, $cProductName, $cManuf, $cPrice, $cCost, $cWeight, $cShortDesc, $cLongDesc, $cStockQty, $cUPC, $mCatId);
    echo "\n";  

}


echo "======== Disabling 0 Product Catagories ===========\n\n";
Cat_Disable_Empty($CM);
echo "======== ============================== ===========\n\n";

unset($CM, $IT, $excel);

//array_push($AAnotmapped, 'Cat not Mapped');
//array_push($AApriceupdated, '### Price Updated');
//array_push($AAimgerror , 'Image Error');

Send_Status_Email();

Mage_Reindex();


echo date("m.d.y g:i a")."\tCompleted\n\n";

//print_r($AAnotmapped);

//print_r($AApriceupdated);

//print_r($AAimgerror);

回答by Hameed

Use functions.
Use $var = null;instead of unset($var);. Unset simply kills the variable reference.

使用函数。
使用$var = null;代替unset($var);。Unset 只会杀死变量引用。


As mentioned on this comment:


正如此评论所述

When you are using unset, the memory will only be freed whenever garbage collector decides, but when you are setting a variable to a different value (null in this case), then you might get some memory freed of course with the cost of CPU.

当您使用 unset 时,只有在垃圾收集器决定时才会释放内存,但是当您将变量设置为不同的值(在这种情况下为 null)时,您当然可能会以 CPU 为代价释放一些内存。

回答by Gilly

Even when you use functions, you would expect the garbage collector to clean up everything in the scope of the function when the function returns.. This is not a guarantee and using functions might even work against you if you're fighting memory usage. Because of the scope, php has to create copies of the variables passed as parameters, which will only add up to the memory usage. You could look into passing references.

即使您使用函数,您也希望垃圾收集器在函数返回时清除函数范围内的所有内容。由于范围的原因,php 必须创建作为参数传递的变量的副本,这只会增加内存使用量。您可以查看传递引用。

The garbage collector will only free up memory when there are CPU cycles available. Usually in loops it wont get a chance, so it will try to do this after the loop, in which case it might already be too late.

垃圾收集器只会在有可用的 CPU 周期时释放内存。通常在循环中它不会有机会,所以它会在循环后尝试这样做,在这种情况下可能已经太晚了。

However you can force the garbage collector to do his round by calling gc_collect_cycles.

但是,您可以通过调用gc_collect_cycles.

Also you can try debugging your code using memory_get_usage()

您也可以尝试使用调试代码 memory_get_usage()