note 88911 added to function.fread
| From: | shaunspiller at dontspammegmail dot com | Date: | Thu, 12 Feb 2009 22:47:03 +0000 |
| Subject: | note 88911 added to function.fread | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-150599@lists.php.net to get a copy of this message | ||
fread has a bug than can cause large memory leaks if you're storing separate strings from
multiple reads, or even just a single string if the length parameter is large.
The strings returned always allocate *length* bytes (the parameter in the call), even if the total
amount of returned data is tiny.
E.g.,:
<?php
file_put_contents('temp.txt', 'a few bytes');
$fp = fopen('temp.txt', 'rb');
echo 'Memory usage: ' . number_format(memory_get_usage(), null, null, ' ') .
"\n";
$x = fread($fp, 1024 * 1024);
fclose($fp);
echo 'Memory usage: ' . number_format(memory_get_usage(), null, null, ' ') .
"\n";
echo 'String length: ' . strlen($x);
?>
Example output:
Memory usage: 67 520
Memory usage: 1 117 056
String length: 11
After just one fread call, the string $x now takes over 1 MB of memory for 11 bytes of data, and
will stay that way until you unset or release it. This affects network streams too.
The bug was apparently dismissed as "won't fix" (or "wont fix" actually):
http://bugs.php.net/bug.php?id=34471
If you want to avoid it, re-alloc the string before storing it, and the wasted memory will
disappear. Specifying a smaller length value avoids creating the large buffer in the first place
too.
E.g.:
<?php
$x = substr(fread($fp, 65536), 0);
?>
----
Server IP: 193.95.141.37
Probable Submitter: 89.100.60.13
----
Manual Page -- http://www.php.net/manual/en/function.fread.php
Edit -- https://master.php.net/note/edit/88911
Del: integrated -- https://master.php.net/note/delete/88911/integrated
Del: useless -- https://master.php.net/note/delete/88911/useless
Del: bad code -- https://master.php.net/note/delete/88911/bad+code
Del: spam -- https://master.php.net/note/delete/88911/spam
Del: non-english -- https://master.php.net/note/delete/88911/non-english
Del: in docs -- https://master.php.net/note/delete/88911/in+docs
Del: other reasons-- https://master.php.net/note/delete/88911
Reject -- https://master.php.net/note/reject/88911
Search -- https://master.php.net/manage/user-notes.php