Как уменьшить виртуальную память путем оптимизации моего кода PHP? - PullRequest
3 голосов
/ 31 декабря 2010

Мой текущий код (см. Ниже) использует 147 МБ виртуальной памяти! Мой провайдер выделил 100 МБ по умолчанию, и процесс завершается после запуска, что вызывает внутреннюю ошибку. Код использует curl multi и должен иметь возможность выполнять цикл с более чем 150 итерациями, одновременно минимизируя виртуальную память. Код ниже установлен только на 150 итераций и по-прежнему вызывает внутреннюю ошибку сервера. На 90 итерациях проблема не возникает.

Как я могу настроить свой код, чтобы уменьшить использование ресурсов / виртуальную память?

Спасибо!

<?php

    function udate($format, $utimestamp = null) {
      if ($utimestamp === null)
        $utimestamp = microtime(true);
      $timestamp = floor($utimestamp);
      $milliseconds = round(($utimestamp - $timestamp) * 1000);
      return date(preg_replace('`(?<!\\\\)u`', $milliseconds, $format), $timestamp);
    }

$url = 'https://www.testdomain.com/';
$curl_arr = array();
$master = curl_multi_init();

for($i=0; $i<150; $i++)
{
    $curl_arr[$i] = curl_init();
    curl_setopt($curl_arr[$i], CURLOPT_URL, $url);
    curl_setopt($curl_arr[$i], CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl_arr[$i], CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($curl_arr[$i], CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_multi_add_handle($master, $curl_arr[$i]);
}

do {
    curl_multi_exec($master,$running);
} while($running > 0);

for($i=0; $i<150; $i++)
{
    $results = curl_multi_getcontent ($curl_arr[$i]);
    $results = explode("<br>", $results);
      echo $results[0];
      echo "<br>";
      echo $results[1];
      echo "<br>";
      echo udate('H:i:s:u');
      echo "<br><br>";
      usleep(100000);
}

?>

Ответы [ 3 ]

2 голосов
/ 03 января 2011

Согласно вашему последнему комментарию ..

Скачать RollingCurl.php.

Надеюсь, это будет достаточным количеством спама для вашего API.

<?php

$url = '________';
$fetch_count = 150;
$window_size = 5;


require("RollingCurl.php");

function request_callback($response, $info, $request) {
    list($result0, $result1) = explode("<br>", $response);
    echo "{$result0}<br>{$result1}<br>";
    //print_r($info);
    //print_r($request);
    echo "<hr>";
}


$urls = array_fill(0, $fetch_count, $url);

$rc = new RollingCurl("request_callback");
$rc->window_size = $window_size;
foreach ($urls as $url) {
    $request = new RollingCurlRequest($url);
    $rc->add($request);
}
$rc->execute();

?>

Просматривая ваши вопросы, я увидел этот комментарий :

Если целью является захват домена, затем с использованием одного из установленных услуги - лучший вариант . Ваш Реализация скрипта вряд ли важно как фактическое соединение и латентность.

Я согласен с этим комментарием.

Кроме того, вы, кажется, задали «тот же вопрос» примерно семьсот раз :

https://stackoverflow.com/users/558865/icer
https://stackoverflow.com/users/516277/icer

Как настроить сервер так, чтобы он быстрее запускал мой PHP-скрипт?
Как я могу перекодировать мой php-скрипт для максимально быстрого запуска?
Как запустить cURL один раз, проверяя доступность домена в цикле? Помогите исправить код пожалуйста
Помогите исправить код php / api / curl пожалуйста
Как уменьшить виртуальную память путем оптимизации моего кода PHP?
Перекрывающиеся HTTPS-запросы?
Несколько запросов https .. как?

Разве тот факт, что вам приходится задавать один и тот же вопрос снова и снова, не говорит вам, что вы делаете это неправильно ?

Этот комментарий от вас:

@ mario: Приветствия. Я соревнуюсь против 2 другие компании для конкретных нДВа. Они новички в игре и они раскупают эти домены в медленное время (до 10 секунд после время чистки). Я немного медленнее на данный момент.

Я вполне уверен, что PHP для учетной записи общего хостинга - это не тот инструмент, который стоит использовать, если вы серьезно пытаетесь обыграть две компании в захвате просроченных доменных имен.

0 голосов
/ 31 декабря 2010
<?php

echo str_repeat(' ', 1024); //to make flush work

$url = 'http://__________/';
$fetch_count = 15;
$delay = 100000; //0.1 second
//$delay = 1000000; //1 second


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);


for ($i=0; $i<$fetch_count; $i++) {

    $start = microtime(true);

    $result = curl_exec($ch);

    list($result0, $result1) = explode("<br>", $result);
    echo "{$result0}<br>{$result1}<br>";
    flush();

    $end = microtime(true);

    $sleeping = $delay - ($end - $start);
    echo 'sleeping: ' . ($sleeping / 1000000) . ' seconds<hr />';
    usleep($sleeping);

}

curl_close($ch);

?>
0 голосов
/ 31 декабря 2010

Результат каждого из 150 запросов сохраняется в памяти PHP, и, по вашим данным, этого недостаточно. Единственный вывод - вы не можете хранить 150 запросов в памяти. У вас должен быть метод потоковой передачи в файлы вместо буферов памяти, или просто уменьшите количество запросов и обрабатывайте список URL-адресов в пакетном режиме.

Чтобы использовать потоки, вы должны установить CURLOPT_RETURNTRANSFER в 0 и реализовать обратный вызов для CURLOPT_WRITEFUNCTION, в руководстве по PHP есть пример:

http://www.php.net/manual/en/function.curl-setopt.php#98491

function on_curl_write($ch, $data)
{
  global $fh;
  $bytes = fwrite ($fh, $data, strlen($data));
  return $bytes;
}

curl_setopt ($curl_arr[$i], CURLOPT_WRITEFUNCTION, 'on_curl_write');

Получение правильного дескриптора файла в обратном вызове остается проблемой для читателя.

...