найти использование памяти - PullRequest
1 голос
/ 18 февраля 2012

У меня есть таблица с ячейками 150x150, каждая из которых имеет цветной фон и небольшое изображение / символ в них. Кроме того, каждая ячейка может иметь ноль или более установленных границ. Пользователь может изменить и добавить границы и изменить цвет ячейки и ячейки. Все это работает довольно хорошо, используя jquery, и это просто обычная HTML-таблица.

В конце пользовательского опыта я делаю PDF этой таблицы для их загрузки. Это большая работа, и она требует времени, что сейчас не моя главная задача. jQuery собирает данные таблицы в массив и отправляет их php, чтобы воссоздать их как изображение с использованием библиотеки gd.

Таким образом, для каждой ячейки я рисовал прямоугольник правильного цвета на большом изображении, загружал изображение символа и передискретизировал его на большое изображение, рисуя границы и изображение, уничтожая изображение символа, это работало, но заняло 1 минуту. Я изменил свою стратегию, чтобы маленькая цветная прямоугольник накладывала на него изображение и помещала его в массив для быстрого использования снова. Это ускорило мое время и уменьшило его до 30 секунд, но теперь я исчерпываю память.

Я разбиваю таблицу на 50 блоков ячеек, каждый из которых помещается на странице, каждый блок превращается в изображение и сохраняется на диск, следующий создается и сохраняется и т. Д. Каждый раз, когда изображение gd уничтожается. Затем все блоки вставляются в PDF.

Итак, после всего этого мой вопрос: как мне определить, где используется память, чтобы я мог попытаться освободить ее? Я разместил основную функцию, я думаю, вызывает проблему ниже. В моем тесте было до 30 различных символов / цветных изображений размером 25pxX25px, это изображения, которые кэшируются в массиве.

Я надеюсь, что предоставил достаточно информации, и моя проблема достаточно ясна.

Спасибо за ваше время, Тодд

//make one "block" of stitches returns image file name.
//function makeStitchChartBlock($img, $startX, $startY, $endX, $endY, $caption, $brand){
function makeStitchChartBlock($stitchChartArray, $startX, $startY, $endX, $endY, $caption, $brand,$blockNumber){
    global $threadColours;
    $stitchCache=array();
    $saveTo = 'result'.$blockNumber.'.jpeg';
    // calculate size of block
    $numRows=($endY-$startY);
    $numColumns=($endX-$startX);
    $heightOfBlock = $numRows*SYMBOL_SIZE; //in pixels --- used to determine size of image to make for block
    $widthOfBlock = $numColumns*SYMBOL_SIZE; //in pixels

    //----plus any extra for captions grid lines
    $heightOfBlock += (($endY-$startY)+1); //each stitch has a grid line before it and the last one also has on after it
    $widthOfBlock += (($endX-$startX)+1);

    // create image size of block to put stitches in
    $newBlockImage = imagecreatetruecolor($widthOfBlock,$heightOfBlock);
    $backStitchColor = imagecolorallocate($newBlockImage, 0, 0, 0);
    // insert caption????
    //draw grid lines
    //$newBlockImage = addGridToImage($newBlockImage);

    //keep track of where to start next cell top left
    $blockX=0; 
    $blockY=0;

    for($y = $startY; $y < $endY; $y++){ //for each pixel in height, move down 1 "row" each iteration
      //echo "<tr>";
      for($x = $startX; $x < $endX; $x++){ // "draws" a row (for each y pixel)
        //rgb(75, 90, 60)
        //x and y are column and row #'s        
        list($r, $g, $b) = getRGBs($stitchChartArray[$y][$x][0]); //get the rgb values for the cell
        $stitchColor = imagecolorallocate($newBlockImage, $r, $g, $b);

        //calculate x & y start positons
        $stitchStartX=($blockX*SYMBOL_SIZE)+$blockX+1; //account for each previous stitch and the grid line, then add one for new grid line
        $stitchStartY=($blockY*SYMBOL_SIZE)+$blockY+1;
        $stitchEndX=$stitchStartX+(SYMBOL_SIZE);
        $stitchEndY=$stitchStartY+(SYMBOL_SIZE);

        /* make a symbol cell image with/without color and save it in the cache */
        if(!isset($stitchCache[$r][$g][$b]))
        {
            //create new image
            $stitchCache[$r][$g][$b] = imagecreatetruecolor(SYMBOL_SIZE,SYMBOL_SIZE);
            $stitchCacheColor = imagecolorallocate($stitchCache[$r][$g][$b], $r, $g, $b);
            //draw colored rectangle
            imagefilledrectangle($stitchCache[$r][$g][$b], 0, 0, SYMBOL_SIZE-1, SYMBOL_SIZE-1, $stitchCacheColor);
            //add the symbol
            $symbolFile=$stitchChartArray[$y][$x][1];
            if($symbolFile){
                $symbolImage = imagecreatefrompng($symbolFile);
                imagecopyresampled ($stitchCache[$r][$g][$b],$symbolImage,0,0,0,0,SYMBOL_SIZE-1,SYMBOL_SIZE-1,imagesx($symbolImage), imagesy($symbolImage) );
                imagedestroy($symbolImage);
            }
        }

        //add image from cache to the block image
        imagecopyresampled ($newBlockImage,$stitchCache[$r][$g][$b],$stitchStartX, $stitchStartY,0,0,SYMBOL_SIZE,SYMBOL_SIZE,SYMBOL_SIZE,SYMBOL_SIZE);

        //add the backstitch lines(borders)
        if($stitchChartArray[$y][$x][2]>1) //top
        {
            imagefilledrectangle($newBlockImage, $stitchStartX, $stitchStartY, $stitchEndX, $stitchStartY+1, $backStitchColor);
        }
        if($stitchChartArray[$y][$x][3]>1) //right
        {
            imagefilledrectangle($newBlockImage, $stitchEndX-1, $stitchStartY, $stitchEndX, $stitchEndY, $backStitchColor);
        }
        if($stitchChartArray[$y][$x][4]>1) //bottom
        {
            imagefilledrectangle($newBlockImage, $stitchStartX, $stitchEndY-1, $stitchEndX, $stitchEndY, $backStitchColor);
        }
        if($stitchChartArray[$y][$x][5]>1) //left
        {
            imagefilledrectangle($newBlockImage, $stitchStartX, $stitchStartY, $stitchStartX+1, $stitchEndY, $backStitchColor);
        }

       //advance x position
       $blockX++;
      }
       //advance y position
      //reset x
      $blockX=0;
      $blockY++;
    }

    imagejpeg($newBlockImage, $saveTo);
    imagedestroy($newBlockImage);


//dump stitch cache
foreach($stitchCache as $r)
{
    foreach($r as $g)
    {
        foreach($g as $b=>$data)
        {
            imagedestroy($data);
        }
    }
}
        return $saveTo;
    }

1 Ответ

1 голос
/ 18 февраля 2012

Я бы начал (если вы этого еще не сделали) с хорошей IDE и отладчиком, так как они будут бесценными инструментами.В этом случае вы можете использовать профилировщик, чтобы определить, где используется память.В случае неудачного ручного отладочного кода ole ', скажем

$memory = memory_get_usage();

в качестве первой строки внутри вашего внутреннего цикла.Затем, когда вы пройдете через отладчик, вы сможете увидеть, где увеличивается объем памяти.

Кстати, использование глобальных переменных, как правило, не очень хорошая идея.Возможно, вы захотите передать $ threadColours в качестве параметра или посмотреть другие способы передачи этих данных в функцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...