Page 1 of 1

Memory leak

Posted: 07 Jan 2010 06:47
by hugobs
Hi,

I'm experiencing a memory leak while running a batch file.

The file consists of a loop, which runs every 30s. Every time the loop runs, it increases the memory requirement by about 1MB.

The memory is not released once the batch is finished, and doesn't show up anywhere else in the task manager. It's simply gone.

That adds up to about 3Gb a day, forcing me to restart the computer eversday. Doesn't sound like much, but I have calculations running for days and by restarting a loose a lot of the calculation effort.

Anyway, even the snippet of code I'm posting leads to a memory leak. I ran it for 1hr (every 4 seconds) and lost around 70MB. With a larger program the leak is higher.

All it does is count the number of .RUN files present in the subfolders. The actual batch is a far more complex, but this appears to be the section responsible for the memory leak.

Code: Select all

@ECHO OFF
setlocal EnableDelayedExpansion
set /a nmax=0
:Bigloop
set /a count=0
for /f %%c in ('dir /b /s ^| find ".RUN"') do (set /a count=!count!+1)
echo count

timeout /T 4 /NOBREAK

goto:Bigloop


Does anyone know why this happens? Is there a way to avoid it?

I also tried things like

Code: Select all

for /f "tokens=*" %%n in ('dir /s /b *.DTF') do (
but it didn't make much of a difference.

By the way, I'm using XP-64bit, but the cmd.exe is only 32 bit. I hope this isn't the reason.

Thanks

Posted: 08 Jan 2010 02:49
by !k

Code: Select all

timeout /T 4 /NOBREAK

This time delay? I am not familiar with this method of delay, where is he?
Try to sleep in another way.

And IMHO

Code: Select all

for /f "delims=" %%a in ('dir /a-d /b /s *.run') do (
more correct

Posted: 11 Jan 2010 16:36
by avery_larry
I've used very similar infinite loops with no memory leaks. Only difference -- the timeout command. If you remove it, does everything work better?

Otherwise, it could be something odd with not releasing the "hidden" cmd that actually runs the dir and find commands.

Other ideas:

1) use find /c instead of set /a count:

Code: Select all

for /f %%c in ('dir /b /s ^| find /c ".RUN"') do set count=%%c
echo %count%


Also, don't need delayedexpansion the way you're doing it:

Code: Select all

for /f %%c in ('dir /b /s ^| find ".RUN"') do set /a count+=1


Final idea -- try findstr instead of find (I've found it to be almost univerally faster -- by a lot). Maybe it'll be different.

Posted: 11 Jan 2010 16:37
by avery_larry
PS -- if the timeout command is just a delay, try:

ping -n 5 -w 999 127.0.0.1 >nul 2>nul


instead.

Posted: 12 Jan 2010 00:58
by hugobs
Thanks for your help.

I had tried several delays, from ping to sleep. I still get the same effect.
I even deleted the timeout: still no change.

However, if I remove the loop and run the file several times instead, there is no memory leak.

Another thing I tried was, instead of

Code: Select all

 setlocal EnableDelayedExpansion 

starting the cmd with the /v option. Also made no difference.

And the problem just got a tad more complicated. I ran the exact same program on another computer (also Win 64 Pro, very similar configuration). On that computer, there is no memory leak.

Is there anything else you can think of that would affect only some computers?