as I'm kind of memory usage paranoid.
because i'd like to hear that my app is using less memory from users of my scripts (usually i publish my scripts to none-ahk users)
so I was always looking for tricks to reduce the memory usage of ahk scripts that i wrote.
but purposeless minimizing window and restoring was the only solution that i 've found so far.
eventually i've found this article at dotnetSpider while googling.
there were few clues to accomplish my dream. especially SetProcessWorkingSetSize() API
It was not that rough to realize. but the result was much like magic even with less effort.
However someone in IRC devaluated it according to This article.
So i've performed Performance Benchmark hundred times with DerRaphael's support.
Here's the code that i've used to benchmark it. (derRaphael wrote it. Thanks)
SetBatchLines, -1 res := "" t1 := 0, t2 := 0 _t1 := 0, _t2 := 0 iterations := 25 outerLoops := 20 loop, %outerLoops% { tooltip, currently @ test: %A_index% t1 := 0, t2 := 0 Loop, %iterations% { VarSetCapacity(Test, 25*1024*1024, 97) DllCall("QueryPerformanceFrequency", "Int64 *", Freq) DllCall("QueryPerformanceCounter", "Int64 *", Start) Loop, 10000 a := chr(NumGet(Test,A_Index,"UChar")) DllCall("QueryPerformanceCounter", "Int64 *", End) wo%A_Index% := (End - Start)/Freq EmptyMem() DllCall("QueryPerformanceFrequency", "Int64 *", Freq) DllCall("QueryPerformanceCounter", "Int64 *", Start) Loop, 10000 a := chr(NumGet(Test,A_Index,"UChar")) DllCall("QueryPerformanceCounter", "Int64 *", End) w%A_Index% := (End - Start)/Freq t1 += wo%A_Index% t2 += w%A_Index% } _t1 += t1/iterations _t2 += t2/iterations res .= "Run" a_index ":`tnormal - " t1/iterations "sec`temty() - " t2/iterations "sec`n" tooltip, currently @ test: A_index } res .= "`nAverage normal " _t1/outerLoops " seconds" . "`nAverage emtpy() " _t2/outerLoops " seconds" MsgBox,0,Results,%res% return EmptyMem(PID="AHK Rocks"){ pid:=(pid="AHK Rocks") ? DllCall("GetCurrentProcessId") : pid h:=DllCall("OpenProcess", "UInt", 0x001F0FFF, "Int", 0, "Int", pid) DllCall("SetProcessWorkingSetSize", "UInt", h, "Int", -1, "Int", -1) DllCall("CloseHandle", "Int", h) }
here's the result in short for lazy people
If you don't use SetBatchLine, -1 while calling this function will reduce the performance like only 10ms though i'm still willing to use it.
but if you use SetBatchLine, -1 there were NO PERFORMANCE REDUCE for Script. sometimes it's even slightly faster though i don't know why
eg) Results from the benchmark with SetBatchLine, -1
Normal : Average 0.007232 seconds
With Func : Average 0.007195 seconds
as dotnetSpider says. after calling this function memory usage will get larger gradually as scripts claims more mem.
but this can be easily solved by using SetTimer (call this func periodically)
However i've read some posts that are negative to use This func periodically.
If you care, Use it only once at Script startup
Furthermore, you can even reduce the memory usage of external apps such as 3DsMax, Photoshop, IE, etc (even explore.exe)
you might be interest in writing Memory Optimization app by using this function.
but applying This function to all Processes may potentially degrade the performance of the system. (from MSDN)
and it's not recommendable to use it on Game Processes
however here's the simple but magical function. use at your own risk.
best use of this function is put it at the end of the AutoExecution Area
or call this function depend on event such as guisize:
Download EmptyMem.ahk to /Lib (Required Win32NT)
Omit parameter to reduce scriptself's mem usage else put target's PID
Example
;This example will reduce mem usage from around 5,000k to 500k Run, taskmgr.exe MsgBox, Remember current memory usage then compare. EmptyMem() Sleep, 5000 Exitapp EmptyMem(PID="AHK Rocks"){ pid:=(pid="AHK Rocks") ? DllCall("GetCurrentProcessId") : pid h:=DllCall("OpenProcess", "UInt", 0x001F0FFF, "Int", 0, "Int", pid) DllCall("SetProcessWorkingSetSize", "UInt", h, "Int", -1, "Int", -1) DllCall("CloseHandle", "Int", h) }
PS. i bet Chris will like it if he's still alive