Tôi có một tập lệnh mà tôi chạy thực hiện nhiều tác vụ và trải qua khoảng 21k lần. Vấn đề là đối với mỗi chỉ mục tôi đang làm nhiều việc khác nhau, mỗi chỉ mục là một sản phẩm trong cơ sở dữ liệu của chúng tôi, tôi đang cập nhật giá bằng cách lấy dữ liệu từ API và lưu sản phẩm, v.v. Tôi có một số khu vực mà tôi đã đặt các cuộc gọi đến memory_get_usage()
trước và sau gần như mọi cuộc gọi phương thức, và tất cả mọi người mà tôi làm dường như làm tăng bộ nhớ. Không có ai làm nhiều hơn những người khác hoặc không phải là đáng chú ý.Sử dụng bộ nhớ PHP trong vòng lặp for giữ ngày càng tăng
Tôi đã cố gắng bỏ đặt tất cả các biến của tôi ở cuối vòng lặp cũng như cố gắng chỉ đặt chúng thành rỗng, nhưng không có vấn đề gì giới hạn bộ nhớ chỉ tiếp tục tăng thông qua mỗi lần lặp.
Có bất kỳ điều gì tôi có thể làm để xóa bộ nhớ này, tôi nghĩ rằng việc tắt các biến được cho là để giải phóng bộ nhớ nhưng dường như không làm như vậy?
EDIT: Tôi quên đề cập đến lý do tại sao tôi bắt đầu điều tra điều này là tôi nhận được lỗi giới hạn bộ nhớ trên máy chủ. Nó không phải luôn luôn xảy ra tại cùng một điểm hoặc thậm chí xảy ra mỗi khi nó được chạy. Đó là lý do tại sao tôi đã cố gắng điều tra nó.
Tập lệnh mất khoảng một giờ để chạy, tôi chạy nó vào buổi sáng khi không có gì khác đang diễn ra và ngay bây giờ nó chỉ nằm trên máy chủ dàn dựng nên không có ai đánh máy chủ.
tôi có thể gửi mã nhưng khá lớn
<?php
if(!function_exists('memory_get_usage')){
include('function.php');
}
echo "At the start we're using (in bytes): ",
memory_get_usage() , "\n\n";
$path = realpath(dirname(__FILE__) . '/../../../../Mage.php');
require_once($path);
Mage::app();
require_once '/lib/ProductUpdate.php';
echo "Starting product update process \n\n";
$productUpdate = new ProductUpdate();
$dealerStoreId = 3;
$volumeDiscountGroupId = 4;
$retailGroupId = Mage_Customer_Model_Group::CUST_GROUP_ALL;
$wholesaleGroupId = 2;
echo "Grabbing all products \n\n";
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
// get the products from the InOrder stored procedure qty since datetime and don't pass a date to get all products, also pass the id of the cron job
$ioProducts = $productUpdate->getProductUpdateProducts('WEB2');
echo "---------------------------\n\n";
echo "Begin Updating Products \n\n";
echo "---------------------------\n\n";
$productCount = 0;
$productUpdate->saveScriptStarted(2);
echo "Before we go into the initial loop we are using (in bytes): ",
memory_get_usage() , "\n\n";
foreach ($ioProducts as $ioProduct) {
$updateProduct = false;
$updateTierPrice = false;
$sku = trim($ioProduct['inp_short_item_number']) . trim($ioProduct['isc_SIZE']) . trim($ioProduct['isc_COLOR']);
echo "Checking item number " . $sku . " \n\n";
echo "Before Loading Product " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
$product = $productUpdate->getProduct();
$productId = $product->getIdBySku($sku);
echo "After Getting Id from sku " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
if ($productId) {
//$product = $productUpdate->getProduct()->load($productId);
echo "After Loading Product " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
echo "WE HAVE A PRODUCT!: " . $product->getName() . "\n\n";
try {
echo "Before Getting Additional Info from InOrder for Product " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
// Since the product is same for parent products as it is for children you should just be able to get the price of the parent and use that.
$additionalInfo = $productUpdate->getItemDetails($ioProduct['inp_short_item_number'], 'WEB2');
echo "After Getting Additional Info from InOrder for Product " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
echo "Before Getting Extra Charges from InOrder for Product " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
$oversizeCharge = $productUpdate->getExtraCharges($ioProduct['inp_short_item_number']);
echo "After Getting Extra Charges from InOrder for Product " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
} catch (Exception $e) {
echo $e->getMessage() . "\n\n";
continue;
}
if (is_array($additionalInfo) && count($additionalInfo) > 0) {
if (isset($oversizeCharge[0]['Shipping Unit Charge']) && $product->getOversizeCharge() != $oversizeCharge[0]['Shipping Unit Charge']) {
$product->setOversizeCharge($oversizeCharge[0]['Shipping Unit Charge']);
$updateProduct = true;
unset($oversizeCharge);
}
if ($product->getPrice() != $additionalInfo[0]['pri_current_price']) {
$product->setPrice($additionalInfo[0]['pri_current_price']);
$updateProduct = true;
unset($additionalInfo);
}
echo "Before Setting Stock Status for Product " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
$product = $productUpdate->setStockStatus($product, $ioProduct);
echo "After Setting Stock Status for Product " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
if ($product->getNeedsUpdate()) {
$updateProduct = true;
}
if ($updateProduct) {
try{
echo "Before Saving Product " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
$productUpdate->saveProduct($product, $ioProduct);
echo "After Saving Product " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
}catch (Exception $e){
echo $e->getMessage() . "\n\n";
continue;
}
}
// Go through and do the same thing for the other 2 web classes to set pricing for the Dealer and Volume wholesale customers
$updateProduct = false;
try {
echo "Before getting Tier Price info for " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
$product = $productUpdate->getProduct()->setStoreId($dealerStoreId)->load($productId);
$additionalInfo = $productUpdate->getItemDetails($ioProduct['inp_short_item_number'], 'WEB3');
//$additionalTierInfo = $productUpdate->getItemDetails($ioProduct['inp_short_item_number'], 'WEB4');
// Get Real Tier Prices based on Customer Type
$retailPriceBreaks = $productUpdate->getItemPriceBreaks($ioProduct['inp_short_item_number'], Mage::getStoreConfig(Lancaster_InOrder_Helper_Data::XML_PATH_RETAIL_PRICE_LIST));
$wholesalePriceBreaks = $productUpdate->getItemPriceBreaks($ioProduct['inp_short_item_number'], Mage::getStoreConfig(Lancaster_InOrder_Helper_Data::XML_PATH_WHOLESALE_PRICE_LIST));
$volumeWholesalePriceBreaks = $productUpdate->getItemPriceBreaks($ioProduct['inp_short_item_number'], Mage::getStoreConfig(Lancaster_InOrder_Helper_Data::XML_PATH_VOLUME_WHOLESALE_PRICE_LIST));
echo "After getting Tier Price infor for " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
} catch (Exception $e) {
echo $e->getMessage() . "\n\n";
continue;
}
if ($product->getPrice() != $additionalInfo[0]['pri_current_price']) {
$product->setPrice($additionalInfo[0]['pri_current_price']);
$updateProduct = true;
}
//The only way to setup multiple price for one website is to set a tier price so we set it to a specific group and the dealer site then go through and set all the other real tier prices
$tierPriceInfo = $product->getData('tier_price');
if (!empty($tierPriceInfo)) {
echo "Before looping through Tier Price infor for " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
foreach ($tierPriceInfo as $tierPrice) {
if ($tierPrice["website_id"] == $dealerStoreId &&
$tierPrice["cust_group"] == $volumeDiscountGroupId &&
$tierPrice["price_qty"] == '1' &&
$tierPrice["price"] != $additionalTierInfo[0]['pri_current_price']) {
$updateTierPrice = true;
}
//todo need to do some refinement to the following, was rushed to put out the logic need to fix so it doesn't update everytime
// need to find if any of the tier prices do not match price as well if there is a price break in InOrder but not in Magento
if (!$updateTierPrice) {
$updateRetail = isUpdateTierPrices($retailPriceBreaks, $tierPrice, $retailGroupId);
$updateWholesale = isUpdateTierPrices($wholesalePriceBreaks, $tierPrice, $wholesaleGroupId);
$updateVolWholesale = isUpdateTierPrices($volumeWholesalePriceBreaks, $tierPrice, $volumeDiscountGroupId);
if (
(count($retailPriceBreaks) > 0 && !$updateRetail['priceTierExists']) &&
(count($wholesalePriceBreaks) > 0 && !$updateWholesale['priceTierExists']) &&
(count($volumeWholesalePriceBreaks) > 0 && !$updateVolWholesale['priceTierExists'])) {
$updateTierPrice = true;
}
if(($updateRetail['updateTierPrice'] || $updateWholesale['updateTierPrice'] || $updateVolWholesale['updateTierPrice'])){
$updateTierPrice = true;
}
}
}
unset($tierPriceInfo);
echo "After looping through Tier Price infor for " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
}
else {
$updateTierPrice = true;
}
if ($updateTierPrice) {
echo "Before setting whether we update Tier Price for " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
//construct the tier price
$website_id = Mage::getModel('core/store')->load($dealerStoreId)->getWebsiteId();
$tierPrices = array(array(
'website_id' => $website_id,
'cust_group' => $volumeDiscountGroupId,
'price_qty' => '1',
'price' => $additionalTierInfo[0]['pri_current_price']
));
updateTierPrices($retailPriceBreaks, $retailGroupId, $tierPrices);
updateTierPrices($wholesalePriceBreaks, $wholesaleGroupId, $tierPrices);
updateTierPrices($volumeWholesalePriceBreaks, $volumeDiscountGroupId, $tierPrices);
$product->setData('tier_price', $tierPrices);
$updateProduct = true;
unset($website_id);
echo "After setting whether we update Tier Price for " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
}
if ($updateProduct) {
try{
echo "Before saving product for Tiered Pricing for " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
// $productUpdate->saveProduct($product, $ioProduct);
echo "After saving product for Tiered Pricing for " . $sku . " we are using (in bytes): ",
memory_get_usage() , "\n\n";
}catch (Exception $e){
echo $e->getMessage() . "\n\n";
continue;
}
}
}
}
$retailPriceBreaks = null;
$wholesalePriceBreaks = null;
$volumeWholesalePriceBreaks = null;
$oversizeCharge = null;
$additionalTierInfo = null;
$additionalInfo = null;
$product = null;
$productCount++;
echo $productCount . " Products have been proceessed \n\n";
}
echo "After running through all products we are using (in bytes): ",
memory_get_usage() , "\n\n";
echo "Peak memory usage for product update scrip (in bytes): ",
memory_get_peak_usage() , "\n\n";
Khá nhiều điều không thể giúp bạn trừ khi bạn đăng mã của mình. – Cfreak
được cập nhật với mã của tôi, lớn của nó mặc dù –