tags:

views:

79

answers:

5

Hi there people, it looks like I'm facing a typical memory outage problem when using a PHP script.

The script, originally developed by another person, serves as an XML sitemap creator, and on large websites uses quite a lot of memory.

I thought that the problem was related due to an algorithm holding data in memory until the job was done, but digging into the code I have discovered that the script works in this way:

  • open file in output (will contain XML sitemap entries)
  • in the loop: ---- for each entry to be added in sitemap, do fwrite
  • close file
  • end

Although there are no huge arrays or variables being kept in memory, this technique uses a lot of memory.

I thought that maybe PHP was buffering under the hood the fwrites and "flushing" data at the end of the script, so I have modified the code to close and open the file every Nth record, but the memory usage is still the same.... I'm debugging the script on my computer and watching memory usage: while script execution runs, memory allocation grows.

Is there a particular technique to instruct PHP to free unsed memory, to force flushing buffers if any?

Thanks

A: 

There has to be some place where data is coming from, take a good look at for each entry to be added in sitemap part of code. It might be that huge DB recordset is loaded at once, or something else, similar.

Anyhow, in order to get around that problem, if you're loading data from a database, try limiting number of results, and then looping to get set after set of data.

mr.b
Do you exclude a weird PHP file management technique? If so I will concentrate somwhere else.Yes data is loaded from a DB, using unbuffered call.
Riccardo
Well, I'm just giving you more places to look at, since you told us yourself that you already did file management stuff (using whichever method - flushing might be a better method, but the end result is the same)
mr.b
A: 

To flush the file buffers use fflush() (http://ch.php.net/manual/en/function.fflush.php) and to free space allocated to variables a unset() (http://ch.php.net/unset) should do it.

You said you tried to close and reopen the file during the process, so flushing the buffer surely isn't the solution. Why not show us some code, memory leaks are sometimes quite unobvious?

svens
- The script is too long to be posted here, exceeds the 600 chars limitWhere would you look for? Some arrays growing somewhere?
Riccardo
Basically yes. If you're using any XML library maybe you should doublecheck that. Also make sure you're not loading hughe portions from the database, as mr.b told you. When working with MySQL PHP loads a lot of data when you query the database, not when you fetch it (for other db systems I don't know). Just listing all files in a directory normally doesn't take much memory, so you must be using some special technique to create your sitemap, which makes it a bit complicated to find out what's wrong without code. You could also temporarly post it on pastebin or similar.
svens
+1  A: 

Change the way the XML file is parsed. I'm guessing it's loading the whole tree into memory.

Use an event parser instead. I've handled XML files with several gigabytes with this.

Artefacto
I have posted the link to the code (http://pastebin.com/ZVf8vZ7z)... it doesn't seem to load the whole map in memory...
Riccardo
+1  A: 

So you are looking for a memory leak in a large PHP program not written by yourself? After you checked the common problems (loading huge db result, not flushing / closing file) without any luck I think you should use a profiler like XDEBUG ( http://xdebug.org/ ) which helps you identify the memory problems. Anything other is just guessing most of the time. I had this experience already a few times...

Max
I have installed xdebug but I'm choking to enable a porperly behaved IDE client. Notepad++ is choking as well :-) Any suggestion for robust (free) IDE client? Any plugin for Dreamweaver CS3?
Riccardo
@Riccardo if you are using xdebug as a profiler, you need a program that can analyze the dumpfile produced by xdebug. See http://xdebug.org/docs/profiler#introduction there are programs listed. I am using xdebug on Windows, using WinCacheGrind to analyze the dumpfiles.
Max
By the way, maybe you should look for a more serious PHP IDE, I can recommend PHP Eclipse or netbeans or if you dont mind the licence fee, activestate komodo is also very good. As far as I know all of them can use xdebug as a debugger (for setting breakpoints in PHP code etc.).
Max
I'm currently testing Netbeans with Xdebug, seems better than clumky Dreamweaver CS3...
Riccardo
but having hard times to make xdebug work on a wordpress install!
Riccardo
Got it to work! I only miss the memory usage
Riccardo
@Riccardo In order to see the memory usage you need to make a dumpfile and analyze that. You enable xdebug profiling with xdebug.profiler_enable in your php.ini and then you set xdebug.profiler_output_dir in your php.ini to the directory where the dump file should be written. Then you use e. g. WinCacheGrund in order to analyze the dump file.
Max
A: 

Here is the code:

link text

Basically

Riccardo