php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #67898 Memory allocation problem - memory not freed
Submitted: 2014-08-24 11:53 UTC Modified: 2014-10-29 23:30 UTC
Votes:3
Avg. Score:4.3 ± 0.9
Reproduced:3 of 3 (100.0%)
Same Version:2 (66.7%)
Same OS:2 (66.7%)
From: tomas at slax dot org Assigned:
Status: Not a bug Package: MySQL related
PHP Version: 5.5.16 OS: Slackware Linux
Private report: No CVE-ID: None
 [2014-08-24 11:53 UTC] tomas at slax dot org
Description:
------------
If I simply get data from MySQL, PHP consumes more memory for every row:

With some older PHP 5.3 versions, it prints constant number all the time, because RAM is properly freed. But with PHP 5.5.15 and 5.5.16 it prints increased amount of RAM for each row, as like the memory is not properly freed. If the mysql table has lots of rows, PHP script ends on trying to allocate more memory than allowed in php.ini

The same problem appears when using mysql_fetch_row(). The same problem appears when using MySQLi extension instead of mysql. The same problem is there if using PHP on command line, the same problem when using PHP as Apache's module.

I compile PHP from sources, using this configure script:

CFLAGS="-O2 -fPIC" ./configure \
--libdir=/usr/lib64 \
--with-libdir=lib64 \
--disable-debug \
--disable-libxml --disable-simplexml --disable-xml --disable-xmlreader --disable-xmlwriter \
--disable-dom \
--enable-mbstring --enable-mbregex \
--without-sqlite3 \
--without-pdo_sqlite \
--without-pear \
--with-mysql \
--with-mysqli \
--enable-ftp \
--with-iconv \
--with-zlib \
--with-png-dir=/usr \
--with-jpeg-dir=/usr \
--with-openssl \
--with-gd \
--with-freetype-dir=/usr \
--enable-gd-native-ttf \
--with-apxs2=/usr/bin/apxs \
--build=x86_64-slackware-linux


Test script:
---------------
$result=mysql_query("SELECT * FROM table");
while($row=mysql_fetch_assoc($result))
{
   echo memory_get_usage()."\n";
}


Expected result:
----------------
I expect PHP to print constant number since it should not allocate more RAM. Like
501320
501320
501320
501320
501320
501320
501320
501320
...

Actual result:
--------------
I get increased number of used RAM
56000376
56001384
56002392
56003400
56004408
56005416
56006424
56007432
56008440
56009448
56010456
56011464
56012472
56013480
56014488
56015496
56016504
56017512
56018520
56019528
56020536
56021544
56022552
56023560
56024568
56025576
56026584
56027592
56028600
56029608
...

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-08-24 17:57 UTC] tomas at slax dot org
The same issue can be observed on PHP 5.4.20.
The same issue can be reproduces on PHP 5.6.0RC4 :(
All compiled on Slackware Linux.
 [2014-08-24 18:59 UTC] tomas at slax dot org
I was able to confirm that the bug is not there in PHP 5.3.29.
So it was introduced in 5.4.x .. oh my god this is serious, so many years ...
I am unable to find sources for PHP 5.4.0 for test. Ideas?
 [2014-08-29 20:45 UTC] tomas at slax dot org
I was unable to get the mentioned memory error with Debian's PHP 5.4.4-14+deb7u14 (tested only with the CLI binary). The memory is properly freed there. However when I took the sources + patches from debian, and compiled on the very same debian box, the memory issue is there again. I tried with simple ./configure --with-mysql --with-mysqli, the compiled binary has the problem with memory which is not freed.

This is very odd. If anybody helps me to replicate Debian's compilation then I could maybe track down what option is responsible...
 [2014-09-01 14:49 UTC] johannes@php.net
mind that
1) mysql_* APIs are deprecated and should not be used,
2) mysql_query is buffering the result set so it's all in memory and
3) your difference comes from using libmysql vs mysqlnd as client library, mysqlnd uses PHP memory and therefore PHP reports more accurate memory usage, with libmysql memory used inside the library is hidden
 [2014-09-01 17:58 UTC] tomas at slax dot org
Thank you for your reply.
I'm not sure what difference are you mentioning.
There is NO DIFFERENCE AT ALL.
The memory problem is there for both, mysql_* and mysqli_* functions. It's the same.
 [2014-09-01 19:22 UTC] tomas at slax dot org
Test it yourself, with this simple script:

<?php

   echo "connecting to database...\n";
   $link=mysqli_connect("localhost",'root','','test');

   echo "creating table with lots of rows...\n";
   mysqli_query($link,"CREATE TEMPORARY TABLE tbl123 LIKE mysql.user");
   for ($i=0;$i<6000; $i++)
   {
      mysqli_query($link,"INSERT IGNORE INTO tbl123 SET host='x".$i."'");
   }

   echo "getting all rows from database\n";
   $result=mysqli_query($link,"SELECT * FROM tbl123");
   while($row=mysqli_fetch_row($result))
   {
      echo "Mem used: ".number_format(memory_get_usage()/1024,1,'.','')." KB\n";
   }

   // expected result: memory usage still the same
   // Actual result: memory usage increases with each row :(

?>
 [2014-10-26 23:17 UTC] php at mcq8 dot be
Please note that the memory is freed when the mysql_query variable gets destroyed.
If you would loop over the mysqli_query part, you would see that the memory is freed.
Furthermore, the amount of memory used when all records have been fetched is approximately the same as not using the mysqlnd so you it is just an optimization or hidden from the memory usage as johannes said
 [2014-10-28 12:34 UTC] tomas at slax dot org
-Status: Open +Status: Closed
 [2014-10-28 12:34 UTC] tomas at slax dot org
I'm going to close this since I've identified the problem and I'll open a new bug for that.
 [2014-10-29 23:30 UTC] rasmus@php.net
-Status: Closed +Status: Not a bug
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 22:01:29 2024 UTC