Когда конкретно вызывается mysql_free_result()?

ivlad

Новичок
Когда конкретно вызывается mysql_free_result()?

Вопрос, скорее, из области управления ресурсами в php, нежели на тему php + mysql, но пишу сюда, ибо не знаю, куда ещё можно было написать :)

В документации написано:
mysql_free_result() only needs to be called if you are concerned about how much memory is being used for queries that return large result sets. All associated result memory is automatically freed at the end of the script's execution.
Фактически, гарантируется, что по завершении работы скрипта для всех хэндлов результатов (которые вернул mysql_query()) автоматом будет вызван mysql_free_result().

В php сборка мусора основана на счётчиках ссылок. Это значит, что если хэндл результата записан в локальную переменную, то при выходе из контекста функции счётчик ссылок на этот ресурс обнулится. Т.е. фактически это значит, что данный хэндл больше нигде не будет использован. А значит было бы правильно в этот момент вызывать mysql_free_result для этого хэндла.

Внимание, вопрос. Когда именно вызывается mysql_free_result? Действительно ли при окончании работы скрипта, или при обнулении счётчика ссылок на ресурс-хэндл?
 

berkut

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

tony2001

TeaM PHPClub
при обнулении счётчика ссылок на ресурс-хэндл.

у всех ресурсов есть деструкторы, у mysql_result - он в том числе вызывает free_result().

>в доке это не упоминается - значит пологаться на такое поведение нельзя.

полагаться можно и нужно.
переменные умирают при refcount == 0, это базовый принцип.
 

Alexandre

PHPПенсионер
в mysql-АПИ эта функция освобождает структуры, задействованные под результат, выполняется перед закрытием или новым запросом. Следуя логике, надо делать так же и в пхп.
Очевидно перед закрытием - смотрится занят ли ресурс, если занят - то освобождается. Очевидно - тоже и перед выполнением следующего запроса, но при этом скорее всего сам ресурс не освобождается free_result, а ссылка заносится в стек. По этому, в целях экономии памяти, логично после обработки запроса, перед выполнением следующего освободить ресурс.
 

tony2001

TeaM PHPClub
пля.
все функции-декструкторы ресурсов, включая mysql_free_result() делают refcount--. и всё, больше ничего они не делают.
настоящее освобождение ресурсов происходит уже внутри, когда refcount == 0.


Alexandre
>при этом скорее всего сам ресурс не освобождается free_result, а ссылка >заносится в стек. По этому, в целях экономии памяти, логично после обработки
>запроса, перед выполнением следующего освободить ресурс.

чушь какая-то.
причем, не скорее всего, а точно.
 

ivlad

Новичок
Короче я понял: никто ничего не знает)

Придётся искать ответ в сишных исходняках пхп. А так не хотелось...)
 

Sluggard

Новичок
все функции-декструкторы ресурсов, включая mysql_free_result() делают refcount--. и всё, больше ничего они не делают.
Функция mysql_free_result() в действительности освобождает память, занимаемую результатом, не зависимо от того, сколько указателей на этот результат существует. После выполнения этой функции, все указатели ссылаются на несуществующий результат и при обращении к ним будут вылезать варнинги.
 

tony2001

TeaM PHPClub
Код:
PHP_FUNCTION(mysql_free_result)
{
    zval **result;
    MYSQL_RES *mysql_result;

    if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &result)==FAILURE) {
        WRONG_PARAM_COUNT;
    }

    if (Z_TYPE_PP(result)==IS_RESOURCE && Z_LVAL_PP(result)==0) {
        RETURN_FALSE;
    }

    ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, result, -1, "MySQL result", le_result);

    zend_list_delete(Z_LVAL_PP(result)); <----------   refcount--
    RETURN_TRUE;
}
еще вопросы есть?
 

berkut

Новичок
так непонятно, если реально он ничего не освобждает, то зачем в мане:
mysql_free_result() will free all memory associated with the result identifier result.
 

Sluggard

Новичок
еще вопросы есть?
Да. И теперь их два.
1. Так что же все таки делает указанный код?
2. Ты не мог бы привести пример, как работать с ресурсом, после функции mysql_free_result()?
 

berkut

Новичок
настоящее освобождение ресурсов происходит уже внутри, когда refcount == 0.
это не заметил. тогда почему
PHP:
$res = mysql_query('SELECT 1') or die(mysql_error());
$copy = $res;
mysql_free_result($res);
var_dump($copy);
mysql_fetch_assoc($copy); 
/*
resource(3) of type (Unknown) 
Warning: mysql_fetch_assoc(): 3 is not a valid MySQL result resource */
как я понимаю, тут refcount не равен нулю. что я не допонимаю?
 
Сверху