Большая утечка памяти в Joomla / PHP .. Что дает? - PullRequest
0 голосов
/ 13 января 2011
 }
public function backup(){
    $app =& JFactory::getApplication();
    $createTablesSQL = $this->_dbo->getTableCreate($this->_tables);
    $databaseName = $app->getCfg("db");
    $data = "--\n-- Database: `{$databaseName}`\n--\n\n";
    foreach ($createTablesSQL as $key => $value){
        $data .= "DROP TABLE IF EXISTS `{$key}`;\n";
        $data .= "\n--\n-- Table structure for table `{$key}`\n--\n";
        $data .= $value . ";\n";
        $tableFields = $this->_dbo->getTableFields($key);
        $this->_dbo->setQuery("SELECT * FROM `{$key}`");
        $this->_dbo->query();
        if($this->_dbo->getNumRows()){
            $data .= "--\n-- Dumping data for table `{$key}`\n--\n";
            $data .= "LOCK TABLES `{$key}` WRITE;\n";
            $fields = array_keys($tableFields);
            $data .= "REPLACE INTO `{$key}` (`".implode("`, `", array_keys($tableFields[$fields[0]]))."`) VALUES \n";
            // Load data from table
            $rows = $this->_dbo->loadRowList();
            $_ = array();
            foreach ($rows as $row){
                foreach ($row as $k => $v){
                    if(!isset($v))
                        $row[$k] = 'NULL';
                    else
                        $row[$k] = "'".addslashes($v)."'";
                    }
                $_[] = "\t(".implode(", ", $row).")";
            }
            $data .= implode(",\n", $_);
            $data .= ";\nUNLOCK TABLES;\n\n";
        }
    }
    // fix dbprefix after getTableCreate
    $tablePrefix = $app->getCfg("dbprefix");
    $data = str_replace($tablePrefix, "#__", $data);
    // write backup file
    $path2Filename = $this->path2BackupFiles;
    $filename = $this->filePrefix . date("Y_m_d_H_i_s", time()) . "_" . CompanyUpdate::getCurrentVersion() . ".sql";
    if(JFile::write($path2Filename . $filename, $data)){
        // compression
        if(false != ($arFile = $this->compressFile($path2Filename, $filename, 'zip', true))){
            return $arFile;
        }else{
            return false;
        }
    }else{
        return false;    
    }
}
/**
 *
 * @param string $path2Filename
 * @param string $filename
 * @param string $type
 * @param bool $cleanUp
 * @return bool
 */
private function compressFile($path2Filename, $filename, $type = 'zip', $cleanUp = false){
    $fullPathFilename = $path2Filename . $filename;     
    $adapter =& JArchive::getAdapter($type); // type compression
    $files2ZIP = array();
    $files2ZIP[0]["name"] = $filename;
    $files2ZIP[0]["data"] = JFile::read($fullPathFilename);
    if($adapter->create($fullPathFilename . "." . $type, $files2ZIP, $type, $path2Filename)){
        if($cleanUp)
            JFile::delete($fullPathFilename);
        return JFile::stripExt($filename) . "." . $type;
    }else{
        return false;
    }
}

} ?>

Кто-нибудь видел здесь утечку?

РЕДАКТИРОВАТЬ: Должны были подумать, чтобы опубликовать ошибку. К сожалению

Фатальная ошибка: недостаточно памяти (выделено 65536000) (попытка выделить 125459 байт) в /home/user2/public_html/administrator/components/com_company/lib/CompanyBaseDManagement.php в строке 395

Согласно Dreamweaver это строка 395: $ row [$ k] = "'" .addslashes ($ v). "'";

Ответы [ 3 ]

3 голосов
/ 14 января 2011

Весь сценарий ужасно неэффективен в памяти. Он должен добавлять данные в виде фрагментов в файл резервной копии, а не считывать всю чертову базу данных в память, а затем запускать на ней функцию str_replace (), а затем, возможно, отправлять ее в функцию сжатия, которая перечитывает файл в память сжимает это. !!!

Честно говоря, единственный простой способ увидеть, как это исправить - увеличить лимит памяти в вашем файле php.ini, попробуйте 128 МБ. Если ваша база данных продолжает расти, то это число будет продолжать расти. Было бы более эффективно удалить этот скрипт и использовать mysqldump + gzip в командной строке, если у вас есть доступ.

0 голосов
/ 14 января 2011

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

http://uk.php.net/manual/en/function.memory-get-usage.php

0 голосов
/ 14 января 2011

Ну, я точно знаю, что редактирование массива, в котором выполняется цикл foreach (например, как этот цикл foreach находится в вашем коде), очень опасно. Я удивлен, что это не выдает ошибку (я подумал по некоторым причинам - подождите, неважно, неправильный язык, который выдает ошибку при редактировании массивов цикла foreach). Я думаю, что там может быть бесконечный цикл. Я видел случаи, когда цикл foreach помещал новый объект в массив, на который он ссылался, в конечном итоге вызывая бесконечный цикл (поскольку в нем никогда не заканчивались элементы для повторения)!

Хорошее начало - разделить ссылочный массив и новый массив с новыми значениями, а затем объединить их или что-то еще после цикла foreach.

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