php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #10204 fgets causes memory leaks
Submitted: 2001-04-06 07:54 UTC Modified: 2001-10-02 18:10 UTC
From: pallmall at hushmail dot com Assigned:
Status: Closed Package: Sockets related
PHP Version: 4.0 Latest CVS (06/04/2001) OS: Linux, BSD and Windows
Private report: No CVE-ID: None
 [2001-04-06 07:54 UTC] pallmall at hushmail dot com
Try this script (tested on windows, linux and open BSD(:

<?php
set_time_limit(0);
while (1) {
  unset($page);
  print "iteration ". ++$c;
  $fp = fsockopen("google.com", 80);
  fwrite($fp, "GET / HTTP/1.0\r\n\r\n");
  while (!feof($fp)) {
    $page .= fgets($fp, 1000);
  }
}
?>

Run it with top or whatever running and watch the memory usage go up and up (not especially quickly because the page is small, but in certain situations I've had memory chewage of 1mb/minute).

Now cf.

<?php
set_time_limit(0);
while (1) {
  unset($page);
  print "iteration ". ++$c;
  $fp = fsockopen("google.com", 80);
  fwrite($fp, "GET / HTTP/1.0\r\n\r\n");
  while (!feof($fp)) {
    $page .= fread($fp, 1000);
  }
}
?>

Memory usage remains constant here.

[This meant I had to rewrite the readLine method in Net_Socket to use fread instead of fgets.]

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2001-04-06 08:54 UTC] wez@php.net
I noticed this last night in the socket code: it uses a simple read-buffering scheme where the read buffer will only grow, so we are effectively storing the everything we have read in memory.

However, I would expect the behaviour to be the same with fread.

I take it the memory usage returns to normal once the page has completed?

--Wez.
 [2001-04-06 09:19 UTC] wez@php.net
Um, yes, the memory usage increases because you are appending an infinite number of copies of the google page to your $page variable.

I can't see any leak in PHP - no leaks are reported by the memory manager.

Can you give me more information about how the memory usage increases, and what you would expect it to be?

Could you try explicitly fclose()ing your $fps too - you might find it useful in reducing memory cost.

--Wez.
 [2001-04-09 06:58 UTC] pallmall at hushmail dot com
> Um, yes, the memory usage increases because you are appending an infinite number of copies
of the google page to your $page variable.

No, that's what the unset is for.

Anyways, here's memory statistics.

On loading script one: 3740kb RAM used after two iterations (RAM should not increase above this level).

After 5 minutes: 4130kb.

Cf script two: 3752kb RAM used initially, and 3752kb after 5 minutes. 

These statistics aren't especially dramatic, but in other conditions it can be catastrophic.

Regarding fclose, no this doesn't help.

There is a problem with fgets but not fread.
 [2001-04-09 07:29 UTC] pallmall at hushmail dot com
> Um, yes, the memory usage increases because you are appending an infinite number of copies
of the google page to your $page variable.

No, that's what the unset is for.

Anyways, here's memory statistics.

On loading script one: 3740kb RAM used after two iterations (RAM should not increase above this level).

After 5 minutes: 4130kb.

Cf script two: 3752kb RAM used initially, and 3752kb after 5 minutes. 

These statistics aren't especially dramatic, but in other conditions it can be catastrophic.

Regarding fclose, no this doesn't help.

There is a problem with fgets but not fread.
 [2001-04-09 07:57 UTC] wez@php.net
Sorry - I somehow missed the unset.

However, unset just removes the variable from the symbol table - try using $page = null instead.

I am in the process of working on a file abstraction for this stuff, so it will be rewritten.

The wierd thing is that I really can't see why fgets would behave differently from fread.  Maybe I haven't looked hard enough.

Please let me know if $page = null works around the problem for now.
 [2001-04-09 11:22 UTC] pallmall at hushmail dot com
> I am in the process of working on a file abstraction for this stuff, so it will be rewritten. 

Hmm. I'm already using an abstraction layer; Net_Socket from PEAR. I had to modify the readLine method to read a byte at a time until it encounters \n to workaround the fgets bug.

> Maybe I haven't looked hard enough. Please let me know if $page = null works around the problem for now.

No it doesn't.
 [2001-09-09 06:12 UTC] sterling@php.net
Can you compile php with --enable-debug, this should report
all leaks, if there are any...
 [2001-10-02 18:10 UTC] sniper@php.net
No feedback. Please reopen if problem still exists with latest CVS. And compile it with --enable-debug before reopening. And add the possible log entries here.

--Jani

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 10:01:28 2024 UTC