26 Stimmen

Wie kann ich den Speicher löschen, während ein langes PHP-Skript läuft? unset()

Mein Skript importiert eine Excel-Datei in eine Produktdatenbank, um Mengen neuer Produkte zu aktualisieren etc....

Ich habe ein Speicherproblem und habe versucht, das Speicherlimit auf das Maximum zu erhöhen (800MB+). Ich habe versucht, die Variablen zu deaktivieren, um den Speicher zwischen den Schleifen freizugeben, aber mir geht immer noch der Speicher aus. Ich habe versucht, den Timeout auf unendlich zu setzen, aber es ist definitiv ein Speicherproblem.

Fehlermeldung aus der Protokolldatei: Fataler Fehler: Erlaubte Speichergröße von 851443712 Bytes ausgeschöpft (versucht, 71 Bytes zuzuweisen)

Keines der Skripte ist in einer Funktion enthalten. Wenn ich die for-Hauptschleife innerhalb einer Funktion erstelle und diese Funktion wiederholt aufrufe, hilft das bei der Garbage Collection und beim Aufräumen des Speichers? Für jede Hilfe oder Anleitung bin ich dankbar.

Skript importieren:

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',                    "xxxxxx@gmail.com");
/* 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);

32voto

Hameed Punkte 2154

Funktionen verwenden.
Verwenden Sie $var = null; anstelle von unset($var); . Unset löscht einfach den Variablenbezug.

Wie in diesem Artikel erwähnt Kommentar :

Wenn Sie unset verwenden, wird der Speicher nur freigegeben, wenn der Garbage Collector entscheidet, aber wenn Sie eine Variable auf einen anderen Wert setzen (in diesem Fall null), dann können Sie etwas Speicher natürlich auf Kosten der CPU freigegeben bekommen.

11voto

Gilly Punkte 8664

Selbst wenn Sie Funktionen verwenden, würden Sie erwarten, dass der Garbage Collector alles im Geltungsbereich der Funktion aufräumt, wenn die Funktion zurückkehrt. Das ist keine Garantie, und die Verwendung von Funktionen könnte sogar gegen Sie arbeiten, wenn Sie mit der Speichernutzung zu kämpfen haben. Wegen des Geltungsbereichs muss php Kopien der als Parameter übergebenen Variablen erstellen, was den Speicherverbrauch in die Höhe treibt. Sie könnten die Übergabe von Referenzen in Betracht ziehen.

Der Garbage Collector gibt nur dann Speicher frei, wenn CPU-Zyklen verfügbar sind. In Schleifen hat er in der Regel keine Gelegenheit dazu. Er wird daher versuchen, dies nach der Schleife zu tun, wobei es in diesem Fall bereits zu spät sein könnte.

Sie können jedoch den Garbage Collector zwingen, seine Runde zu machen, indem Sie gc_collect_cycles .

Sie können auch versuchen, Ihren Code zu debuggen, indem Sie memory_get_usage()

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X