2012-05-11 123 views
13

我的腳本導入excel文件到產品數據庫來更新數量新產品等....如何在運行長PHP腳本時清除內存?嘗試unset()

我有內存問題,我試圖提高內存限制爲最大(800MB +)。我試圖取消設置變量以釋放循環之間的內存,但仍然耗盡內存。我試圖將超時設置爲無限,但它絕對是一個內存問題。從日誌文件

錯誤消息: 致命錯誤:用盡851443712個字節允許存儲器大小(試圖分配71個字節)的腳本

沒有被包含在功能。如果我在函數內部創建主循環並重復調用那個幫助垃圾收集和清理內存的函數?任何幫助或指導將不勝感激。

導入腳本:

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); 
+0

解封變量您的代碼重新分配他們在這裏獲得你什麼都不對了。什麼版本的PHP?這些功能中有些什麼?你的excel讀者是急於還是懶惰地提取數據?在達到mage_reindex之前是否耗盡內存? –

+0

Hi Cory,PHP版本是5.2.9,腳本在它死前通過約3700-4000種產品。我不確定它是懶惰/渴望的,是的它在調用mage_reindex之前耗盡內存。 –

回答

17

使用的功能。
使用$var = null;而不是unset($var);。取消設置只會殺死變量引用。


作爲此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.

+1

「殺死變量引用」有什麼問題? – deceze

+8

@deceze殺死是錯的,男人...... –

+5

@Michael這就是爲什麼它很好地稱爲* unset *,而不是'kill_with_extreme_prejudice()'。 :) – deceze

2

即使你使用的功能,你所期望的垃圾收集清理的功能範圍的一切時,函數返回。這是不如果你打擊內存使用,保證和使用功能甚至可能會對你產生不利影響。由於範圍的原因,php必須創建作爲參數傳遞的變量副本,這隻會增加內存使用量。你可以看看通過引用。

當有CPU週期可用時,垃圾回收器將只釋放內存。通常在循環中它不會有機會,所以它會在循環之後嘗試這樣做,在這種情況下它可能已經太晚了。

但是,您可以通過調用gc_collect_cycles來強制垃圾回收器完成他的回合。

您也可以嘗試使用調試memory_get_usage()

+0

通過引用傳遞是您可能傳遞的大數據參數的一個好主意。如果您不打算,請注意不要在函數中編輯該參數。另外,調試總是......一個好主意。 – arikin

相關問題