Sign in to follow this  
Followers 0
Simon818

Repeated use of the ShellExecute command leads to serious memory leak

5 posts in this topic

I may need to repost this in the bugs section, but I'm still not completely convinced I'm doing everything properly, so thought I'd get another opinion or three, first.

I have a program on my system that runs other applications or scripts at the press of a hotkey. Since I need a bit of flexibility as far as what the script does with the file, I'm using ShellExecute instead of Run. I've noticed that after repeated uses of this command, my script, or the script in charge of executing said ShellExecute command, grows to astonishingly high memory usage. After two days of frequent computer use without restarting either the program or, of course, the machine, the script was using around 300 mb of memory.

To test this theory, I wrote a simple test script that I compiled into an executable. This was a one line script:

$string=""

Obviously, nothing of substance here. It's intended to open, do nothing, and close.

I then wrote another test script which I'll paste below the end of this post.

The result was the same, without the added functionality of my program. As you'll see, there is nothing going on besides a simple loop, a couple of variables being tracked, and the infamous ShellExecute commands. If you change ShellExecute and ShellExecuteWait to Run and RunWait, the problem goes away entirely.

I'm running windows XP pro with service pack 3, on an HP laptop with a 2.10 ghz duol core processor and 4 gb of ram, turned 3 because of 32 bit. I'm using the latest AutoIt release as of January of this year, but I re-downloaded the setup file mere hours ago to make sure I wasn't out of date.

Here is my test script. Note that if you plan on personally testing it, you'll need to have the aforementioned one-line script in the same folder as this one and named "test.exe", unless you plan on modifying my code accordingly. It will also be paused until you press the pause key. If you don't have this key on your keyboard, you'll also have to modify those lines accordingly.

If I unpause this script for around a minute, memory usage is way over 200 mb.

#NoTrayIcon

hotkeyset("^{pause}","quit")

hotkeyset("{pause}","pause")

$paused=1

while 1

if $paused=0 then

ShellExecute("test.exe")

ShellExecuteWait("test.exe")

else

sleep(50)

endif

wend

func pause()

if $paused=1 then

$paused=0

else

$paused=1

endif

endfunc

func quit()exit

endfunc

Share this post


Link to post
Share on other sites



Ya don't have to write both shellexecute and shellexecutewait in ur script


----------------------------------------

:bye: Hey there, was I helpful?

----------------------------------------

My Current OS: Win8 PRO (64-bit); Current AutoIt Version: v3.3.8.1

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Hi,

Your ShellExecuteWait is executed multiple times if you shot the pause key two times before the process is launched.

Here you go :

#NoTrayIcon

Global $blPaused = True, $blExecuted = False

HotKeySet("^{pause}", "quit")
HotKeySet("{pause}", "pause")

While 1
If Not $blPaused Then
If Not $blExecuted Then
ShellExecute("test.exe")
$blExecuted = True
EndIf
Else
Sleep(50)
EndIf
WEnd

Func pause()
If Not $blPaused Then
ProcessClose("test.exe") ;avoid multiple test instance?
$blExecuted = False
EndIf

$blPaused = Not $blPaused
EndFunc   ;==>pause

Func quit()
Exit
EndFunc   ;==>quit

Edit : btw, please use the autoit tags to write your code.

Br, FireFox.

Edited by FireFox

 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

Hi,

I realize the code isn't the most neatly written thing in the world, but that really isn't the main problem. In any script, no matter the neatness or tidiness of the code, I still see major memory leaks. Even something as simple as a loop that executes a program over and over again would see increased memory usage. I'm unfortunately not sure how the autoit tagging system works here. I'm using a screen reader, and something about this forum system really disagrees with it (probably the fact that most of the toolbar buttons seem not to have proper text labels). If there is some kind of actual text I can write before and after the code, that should work fine.

If I execute the corrected script on my system and watch the memory usage from task manager, I see it increasing every time the program is run. I put the ShellExecute and ShellExecuteWait commands in for two reasons.

1. It allows the script to run more instances of the test application and makes the memory leak more obvious.

2. It proves that both commands have the same issue.

Bottom line: With every use of the ShellExecute command in a script, the memory usage for that script grows. Maybe this is an issue only seen on my machine, but unfortunately I have no way of testing this currently, as my only other computer is a mac.

Share this post


Link to post
Share on other sites

@Simon818

I have launched over and over again a process and the script memory usage is constant, maybe you can try Run func.

But I see that I set (edit: you set) a sleep only if the pause is not activated which is bad for CPU, so here is the fixed one :

#NoTrayIcon

Global $blPaused = True, $blExecuted = False

HotKeySet("^{pause}", "_Exit")
HotKeySet("{pause}", "_SwitchPause")

While 1
If Not $blPaused Then
If Not $blExecuted Then
ShellExecute("test.exe")
;or Run()?
$blExecuted = True
EndIf
EndIf

Sleep(50)
WEnd

Func _SwitchPause()
If Not $blPaused Then
ProcessClose("test.exe") ;avoid multiple test instance?
$blExecuted = False
EndIf

$blPaused = Not $blPaused
EndFunc   ;==>pause

Func _Exit()
Exit
EndFunc   ;==>quit

Br, FireFox.


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0