# drastic memory consumption with a sequence of exceptions

- Thread: https://externals.io/message/17698
- Original archive: https://news-web.php.net/php.internals/17698
- Started by Ron Korving on 2005-08-09T15:07:17+00:00
- Messages: 9
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #17698 — Ron Korving — 2005-08-09T15:07:17+00:00

URL: https://externals.io/message/17698#17698

I've noticed that in a script of mine, memory consumption can explode quite
drastically when Exceptions are thrown, opposed to very normal memory
consumption when exceptions are not thrown.

This is the idea:

<?
class Obj
{
  function process($i)
  {
    // do a lot of stuff, occupy a lot of memory within the scope of this
function
    throw new Exception("error");
  }
}

$obj = new Obj();
$errors = array();

for ($i=0; $i < 60; $i++)
{
  try
  {
    $obj->process();
  }
  catch (Exception $e)
  {
    $errors[] = $e->getMessage();
  }
}
?>

When exceptions are not thrown, memory consumption is normal. The method's
local vars are freed and not much more memory is used in the 50th pass
compared to the 1st. But when exceptions are thrown, memory consumption
increases quite a bit every pass. In the end (within the 60 passes of my
loop) over 8 MB's are used.

Of course, I can unset a lot of data before throwing exceptions to free up
memory and the problem will be solved. But it would be nicer if the cleanup
would happen as an exception is thrown.

Can this be considered a bug or is this behavior known and accepted?

Ron

---

## #17699 — Ron Korving — 2005-08-09T15:16:37+00:00

URL: https://externals.io/message/17698#17699 · In reply to: #17698

It is very likely that this has something to do with DOM. It's a huge piece
of code though, making it hard to test where the problem really lies.

""Ron Korving"" <r.korving@xit.nl> schreef in bericht
news:BD.4F.04646.AA6C8F24@pb1.pair.com...
> I've noticed that in a script of mine, memory consumption can explode
quite
> drastically when Exceptions are thrown, opposed to very normal memory
> consumption when exceptions are not thrown.
>
> This is the idea:
>
> <?
> class Obj
> {
>   function process($i)
>   {
>     // do a lot of stuff, occupy a lot of memory within the scope of this
> function
>     throw new Exception("error");
>   }
> }
>
> $obj = new Obj();
> $errors = array();
>
> for ($i=0; $i < 60; $i++)
> {
>   try
>   {
>     $obj->process();
>   }
>   catch (Exception $e)
>   {
>     $errors[] = $e->getMessage();
>   }
> }
> ?>
>
> When exceptions are not thrown, memory consumption is normal. The method's
> local vars are freed and not much more memory is used in the 50th pass
> compared to the 1st. But when exceptions are thrown, memory consumption
> increases quite a bit every pass. In the end (within the 60 passes of my
> loop) over 8 MB's are used.
>
> Of course, I can unset a lot of data before throwing exceptions to free up
> memory and the problem will be solved. But it would be nicer if the
cleanup
> would happen as an exception is thrown.
>
> Can this be considered a bug or is this behavior known and accepted?
>
> Ron

---

## #17700 — Ron Korving — 2005-08-09T15:27:26+00:00

URL: https://externals.io/message/17698#17700 · In reply to: #17699

The problem occurs in this particular situation:

public function process($data)
{
  $largeResultSet = $this->xmlParser->parseString($data);

  foreach ($largeResultSet as &$item)
  {
    throw new Exception("error");
  }
}

It only happens if the exception is thrown from within the foreach(). It
seems the $largeResultSet is not freed in this case. Using the foreach by
reference or not (&$item or $item) does not make a difference.

Ron


""Ron Korving"" <r.korving@xit.nl> schreef in bericht
news:21.AF.04646.20AC8F24@pb1.pair.com...
> It is very likely that this has something to do with DOM. It's a huge
piece
> of code though, making it hard to test where the problem really lies.
>
> ""Ron Korving"" <r.korving@xit.nl> schreef in bericht
> news:BD.4F.04646.AA6C8F24@pb1.pair.com...
> > […]
> quite
> > […]
this
> > […]
method's
> > […]
up
> > […]
> cleanup
> > […]

---

## #17726 — Andi Gutmans — 2005-08-09T19:40:09+00:00

URL: https://externals.io/message/17698#17726 · In reply to: #17699

Can you send a complete script which also passes $data that reproduces the 
problem? Thanks.

At 05:27 PM 8/9/2005 +0200, Ron Korving wrote:
>The problem occurs in this particular situation:
>
>public function process($data)
>{
>   $largeResultSet = $this->xmlParser->parseString($data);
>
>   foreach ($largeResultSet as &$item)
>   {
>     throw new Exception("error");
>   }
>}
>
>It only happens if the exception is thrown from within the foreach(). It
>seems the $largeResultSet is not freed in this case. Using the foreach by
>reference or not (&$item or $item) does not make a difference.
>
>Ron
>
>
>""Ron Korving"" <r.korving@xit.nl> schreef in bericht
>news:21.AF.04646.20AC8F24@pb1.pair.com...
> > […]
>piece
> > […]
>this
> > […]
>method's
> > […]
>up
> > […]

---

## #17770 — Ron Korving — 2005-08-10T06:47:25+00:00

URL: https://externals.io/message/17698#17770 · In reply to: #17726

Okay Andi, the script in this message is as simple as it gets. I used a
syslog file to create a load of data in this case, but of course you can use
any (text) file for this.

#!/usr/bin/php5
<?
  function process()
  {
    $data = file("/var/log/syslog.0");

    foreach ($data as $line)
      throw new Exception("error");
  }

  for ($i=0; $i < 30; $i++)
  {
    echo `memory_get_usage()`."\n";

    try { process(); } catch (Exception $e) { }
  }
?>

This is the output it gives me (PHP 5.0.4 btw):

40232
309528
578880
846720
1114560
1382400
1650240
1918080
2185920
2453760
2721600
2989440
3257280
...
7810560


I consider this a bug or a flaw anyway. I hope you agree.

Ron


"Andi Gutmans" <andi@zend.com> schreef in bericht
news:5.1.0.14.2.20050809123954.03491eb0@localhost...
> Can you send a complete script which also passes $data that reproduces the
> problem? Thanks.
>
> At 05:27 PM 8/9/2005 +0200, Ron Korving wrote:
> > […]
explode
> > […]
memory
> > […]
pass
> > […]
consumption
> > […]
of my
> > […]
free
> > […]

---

## #17773 — Marcus Boerger — 2005-08-10T09:45:22+00:00

URL: https://externals.io/message/17698#17773 · In reply to: #17770

Hello Ron,

Wednesday, August 10, 2005, 8:47:25 AM, you wrote:

> Okay Andi, the script in this message is as simple as it gets. I used a
> syslog file to create a load of data in this case, but of course you can use
> any (text) file for this.

> #!/usr/bin/php5
> <?
>   function process()
>   {
>     $data = file("/var/log/syslog.0");

>     foreach ($data as $line)
>       throw new Exception("error");

What makes you think the file would be closed. Erm the array deleted? And
that is your problem you are unnecessarily reading all the file into an
array. Try using the same with FileObject instead, which should reduce
memory usage a lot:

foreach(FileObject($file) as $data) throw new Exception("error");

But of course you only did that to demonstrate the memory problem which in
fact simply means that we don't do a full stack cleanup like c++ would do
here (php != c++).

In php we do the cleanup at script termination. That is also the reason
why php is not perfectly suitable for console apps especially when it comes
to daemons.

best regards
marcus

---

## #17774 — Ron Korving — 2005-08-10T09:54:33+00:00

URL: https://externals.io/message/17698#17774 · In reply to: #17773

You're right, using that file to create a big piece of data was just for
demonstration purposes. In my personal case it's XML parsing. The way I read
what you just said is that this is behavior by design. But if I don't throw
Exceptions, memory usage stays constant. Throwing and catching these
exceptions are the exception-to-the-rule.

Nonetheless, if this is truly by design.. maybe that's something to look
into for PHP6.

Ron

"Marcus Boerger" <helly@php.net> schreef in bericht
news:124244453.20050810114522@marcus-boerger.de...
> Hello Ron,
>
> Wednesday, August 10, 2005, 8:47:25 AM, you wrote:
>
> > […]
use
> > […]
>
> > […]
>
> > […]
>
> What makes you think the file would be closed. Erm the array deleted? And
> that is your problem you are unnecessarily reading all the file into an
> array. Try using the same with FileObject instead, which should reduce
> memory usage a lot:
>
> foreach(FileObject($file) as $data) throw new Exception("error");
>
> But of course you only did that to demonstrate the memory problem which in
> fact simply means that we don't do a full stack cleanup like c++ would do
> here (php != c++).
>
> In php we do the cleanup at script termination. That is also the reason
> why php is not perfectly suitable for console apps especially when it
comes
> to daemons.
>
> best regards
> marcus

---

## #17787 — Andi Gutmans — 2005-08-10T14:08:39+00:00

URL: https://externals.io/message/17698#17787 · In reply to: #17773

Hi Ron,

Indeed exception may lead to leaks in certain cases. We do try and cleanup 
as much as possible but the situation you describe is hard to detect. I 
will however put it on our TODO list because this case could possibly be 
improved on.

Andi

At 11:54 AM 8/10/2005 +0200, Ron Korving wrote:
>You're right, using that file to create a big piece of data was just for
>demonstration purposes. In my personal case it's XML parsing. The way I read
>what you just said is that this is behavior by design. But if I don't throw
>Exceptions, memory usage stays constant. Throwing and catching these
>exceptions are the exception-to-the-rule.
>
>Nonetheless, if this is truly by design.. maybe that's something to look
>into for PHP6.
>
>Ron
>
>"Marcus Boerger" <helly@php.net> schreef in bericht
>news:124244453.20050810114522@marcus-boerger.de...
> > […]
>use
> > […]
>comes
> > […]

---

## #17792 — Ron Korving — 2005-08-10T14:47:47+00:00

URL: https://externals.io/message/17698#17792 · In reply to: #17787

Thanks, that's all I would ever ask for :)

Ron

"Andi Gutmans" <andi@zend.com> schreef in bericht
news:5.1.0.14.2.20050810070706.042bcec0@localhost...
> Hi Ron,
>
> Indeed exception may lead to leaks in certain cases. We do try and cleanup
> as much as possible but the situation you describe is hard to detect. I
> will however put it on our TODO list because this case could possibly be
> improved on.
>
> Andi
>
> At 11:54 AM 8/10/2005 +0200, Ron Korving wrote:
> > […]
read
> > […]
throw
> > […]
used a
> > […]
can
> > […]
And
> > […]
an
> > […]
which in
> > […]
do
> > […]
reason
> > […]
