We use three stay open applescripts, that use “On Idle” and “End Idle” in Mountain Lion. Since 10.8, these scripts have been causing a memory leak (Activity Monitor, WindowServer), and if we don’t restart the computer they run on each day, eventually, the computer freezes due to lack of memory. This is a known bug in OSX, but is there another way to keep the script running without having the memory leak issue?
Does anyone else have this issue?
Well, you’re working around a bug, so I suppose you may consider a hack.
Perhaps schedule quitting after a timeout & then an appropriately scheduled relaunch (via iCal?)
Correct, AppleScript isn’t memory-leak-safe. Normally you’ll run a script and close it afterwards, so the leaks won’t grow into something noticable. The way you write your code has some small effects on the memory management but you’re never be able to get all of it out there. So instead of keeping your AppleScript instance open, it’s better to close them and move your interval outside AppleScript.
I always launch my scripts using launchd (lingon is an useful tool that makes managing launchd easier).
Hi Ryan,
There is another way with pmset. It might depend though. What’s the idle time and maybe someother things in the script. Another thing is maybe your script is using up memory with the variables.
Edited: it was launched to run scripts at certain times. I didn’t see DJ Bazzie Wazzies post. It works very well also.
gl,
kel
Are you sure your applet didn’t leak memory in earlier versions of OS X?
If you hope to see it fixed, make sure you log a bug report with Apple.
Here is the script we have, which leaks memory.
property dropboxPath : “Prepress:PDF_4900R” as alias
property epsonproofPath : “Prepress:PDF_4900R:EPSONProof” as alias
property excluded : “Prepress:PDF_4900R:Failed” as alias
–Nutrition
property nutrition : “Catalogs:Catalog Production:CATALOGS:1076_2014_Nutrition:Final PDF Files:Approved Regular Version” as alias
–International Healthcare
property ihc : “Catalogs:Catalog Production:CATALOGS:1073_2014_IntHealthCare:Final PDF Files” as alias
–Physical Education
property physical : “Catalogs:Catalog Production:CATALOGS:1102_2015_PhyEd:Final PDF Files:Approved Regular Version” as alias
–Benton Kirby July
property bkjuly : “Catalogs:Catalog Production:CATALOGS:1087_2015_BentonKirby_July:Final PDF Files” as alias
–Arts and Crafts BTS
property acbts : “Catalogs:Catalog Production:CATALOGS:1077_2014_Arts&Crafts_BTS:Final PDF Files” as alias
–Early Learning
property earlylearning : “Catalogs:Catalog Production:CATALOGS:1107_2015_EarlyLearning:Final PDF Files” as alias
on idle
set dropboxitems to (list folder dropboxPath without invisibles) -- list of names
if dropboxitems is not {} then
delay 10
tell application "Finder"
set folpath to (dropboxPath as text)
repeat with n in dropboxitems
try
set f to (file (folpath & n))
--Nutrition
if n begins with "14NUT" then
duplicate f to epsonproofPath
move f to nutrition with replacing
delete f
end if
--International Healthcare
if n begins with "14IHC" then
duplicate f to epsonproofPath
move f to ihc with replacing
delete f
end if
--Physical Education
if n begins with "15PEp" then
duplicate f to epsonproofPath
move f to physical with replacing
delete f
end if
tell application "Finder"
set trashCount to count of items of trash
if trashCount is greater than 9 then
empty trash
end if
--Benton Kirby July
if n begins with "15BK" then
duplicate f to epsonproofPath
move f to bkjuly with replacing
delete f
end if
--Arts and Crafts BTS
if n begins with "14ACBTS" then
duplicate f to epsonproofPath
move f to acbts with replacing
delete f
end if
--Early Learning
if n begins with "15ELp" then
duplicate f to epsonproofPath
move f to earlylearning with replacing
delete f
end if
end tell
-- 6. moves PDF files that are not listed in the catalog list to a Failed folder and opens that folder window
move f to excluded with replacing
display dialog "This PDF wasn't moved to a final destination. It will be located in the Failed folder. Please move this to it's appropriate location." buttons "OK" default button 1
open folder excluded
set bounds of container window of folder excluded to {200, 200, 600, 400}
end try
end repeat
end tell
end if
return 5 -- return to this handler after 5 seconds
end idle
Rather than polling a folder with a stay open script I’d recommend to use a folder action or “ still more reliable “ a launchd agent with the WatchPaths key.
The benefit is much less CPU and RAM and no memory leaks because the attached script is not required to stay open
PS: this is a more effective version of your script.
It works with string paths instead of alias specifiers (also to be able to compile it on machines which lack the locations)
It uses lists (prefixList, destinationList) and a repeat loop to process the files.
When a prefix matches and the file has been moved the inner loop is left.
The files are immediately deleted with a shell command.
In case of an error the error message is logged into ~/Library/Logs. The log can be watched in Console.app
However I haven’t tested the script, the environment iss too special
property dropboxPath : "Prepress:PDF_4900R:"
property epsonproofPath : dropboxPath & "EPSONProof:"
property excluded : dropboxPath & "Failed:"
property catalogProductionFolder : "Catalogs:Catalog Production:CATALOGS:"
--Nutrition
property nutrition : catalogProductionFolder & "1076_2014_Nutrition:Final PDF Files:Approved Regular Version:"
--International Healthcare
property ihc : catalogProductionFolder & "1073_2014_IntHealthCare:Final PDF Files:"
--Physical Education
property physical : catalogProductionFolder & "1102_2015_PhyEd:Final PDF Files:Approved Regular Version:"
--Benton Kirby July
property bkjuly : catalogProductionFolder & "1087_2015_BentonKirby_July:Final PDF Files:"
--Arts and Crafts BTS
property acbts : catalogProductionFolder & "1077_2014_Arts&Crafts_BTS:Final PDF Files:"
--Early Learning
property earlylearning : catalogProductionFolder & "1107_2015_EarlyLearning:Final PDF Files:"
property prefixList : {"14NUT", "14IHC", "15PEp", "15BK", "14ACBTS", "15ELp"}
property destinationList : {nutrition, ihc, physical, bkjuly, acbts, earlylearning}
property logName : "DropboxDistributionError.log"
on idle
set dropboxitems to (list folder alias dropboxPath without invisibles) -- list of names
set initialDelay to true
repeat with anItemName in dropboxitems
if initialDelay then
delay 10
set initialDelay to false
end if
try
set processed to false
set filePath to dropboxPath & anItemName
repeat with i from 1 to (count prefixList)
set namePrefix to item i of prefixList
set destinationFolder to item i of destinationList
if anItemName begins with namePrefix then
tell application "Finder"
duplicate file filePath to folder epsonproofPath
move file filePath to folder destinationFolder with replacing
do shell script "rm " & quoted form of POSIX path of filePath
end tell
set processed to true
exit repeat
end if
end repeat
if not processed then
tell application "Finder"
move file filePath to folder excluded with replacing
display dialog "This PDF wasn't moved to a final destination. It will be located in the Failed folder. Please move this to it's appropriate location." buttons "OK" default button 1
open folder excluded
set bounds of container window of folder excluded to {200, 200, 600, 400}
end tell
end if
on error e
logError(e)
end try
end repeat
return 5 -- return to this handler after 5 seconds
end idle
on logError(theError)
set logFolder to (path to library from user domain as text) & "Logs:"
tell (current date) to set timeStamp to short date string & space & time string & ": "
set logFile to logFolder & logName
try
set the logStream to open for access file logFile with write permission
set logFileEof to get eof of the logStream
write timeStamp & theError & return to logStream starting at eof as «class utf8»
close access logStream
on error
try
close access file logFile
end try
end try
end logError
If you don’t want to use WatchPaths as I suggested and want to keep polling you can also take a look at Bash.
#!/bin/sh
while sleep 5
do
#Launch code for your AppleScript here
done
You’re moving the idle handler again outside AppleScript and will safe you from memory leaks.