I've simplified it down to code which allocates script instances and stores them in a NSDictionary.
On my 4GB memory Mac Mini, setting the number of objects to allocate at 100 works fine.
At 200 it runs to completion but logs an "operation couldn't be completed" message before the "DONE" appears. When I add this code to a large ASOC project and have it execute at application startup, later code in my project hits random errors and/or crashes at random lines of execution.
At 1000 the "operation couldn't be completed" emits twice and the application goes into an infinite memory allocating loop. Within 3 seconds Application Monitor says it's real memory usage is 1.1GBytes. It slowly keeps moving up from there as paging starts kicking in. [WARNING: The first time this bug occurred in my large ASOC project, I didn't know anything was wrong. After a few minutes into execution I lost my keyboard and mouse and was forced to reboot. When XCode was next started all snapshots for all projects were gone. Syslog showed XCode's secretly mounted snapshot file had been corrupted and the automatic "repair" of the volume had deleted all its contents."]
Note: In none of these cases does the on error handler ever execute.
property NSMutableDictionary : class "NSMutableDictionary"
property DataItemClass : class "DataItem"
property dict : missing value
script TestMemoryLimitAppDelegate
property parent : class "NSObject"
on applicationWillFinishLaunching_(aNotification)
try
set dict to NSMutableDictionary's dictionaryWithCapacity_(10)
set limit to 100 -- works
set limit to 200 -- emits log message yet appears to finish normally. In reality, internal memory appears to be clobbered
set limit to 500 -- emits log messages yet appears to finish normally. In reality, internal memory appears to be clobbered
set limit to 1000 -- hangs infinitely allocating memory
log "creating " & limit & " objects"
repeat with i from 1 to limit
set anotherObj to DataItemClass's NewDataItem_(i as string)
dict's addObject_forKey_(anotherObj, i as string)
end repeat
log "DONE"
current application's NSApp's terminate_(me)
on error errMsg number errorNumber
log "on error: " & errMsg & ": " & errorNumber
end try
end applicationWillFinishLaunching_
on applicationShouldTerminate_(sender)
return current application's NSTerminateNow
end applicationShouldTerminate_
end script
script DataItem
property parent : class "NSObject"
property aString : missing value
on NewDataItem_(aString)
set newObj to DataItemClass's alloc()'s init()
newObj's setString_(aString)
return newObj
end NewDataItem_
on setString_(theString)
set my aString to theString as string
end setString_
end script
-- Dave
2011-01-20 02:40:28.520 TestMemoryLimit[32492:a0f] creating 100 objects
2011-01-20 02:40:28.632 TestMemoryLimit[32492:a0f] DONE
LOG OF 200 OBJECT ALLOCATION
2011-01-20 02:39:46.673 TestMemoryLimit[32476:a0f] creating 200 objects
2011-01-20 02:39:46.802 TestMemoryLimit[32476:a0f] *** -[DataItem setString:]: The operation couldn’t be completed. (OSStatus error -1750.) (error -1750)
2011-01-20 02:39:46.893 TestMemoryLimit[32476:a0f] DONE
LOG OF 500 OBJECT ALLOCATION
2011-01-20 02:41:28.330 TestMemoryLimit[32523:a0f] creating 500 objects
2011-01-20 02:41:28.488 TestMemoryLimit[32523:a0f] *** -[DataItem setString:]: The operation couldn’t be completed. (OSStatus error -1750.) (error -1750)
2011-01-20 02:41:28.678 TestMemoryLimit[32523:a0f] *** -[DataItem setString:]: The operation couldn’t be completed. (OSStatus error -1750.) (error -1750)
2011-01-20 02:41:29.207 TestMemoryLimit[32523:a0f] DONE
LOG OF 1000 OBJECT ALLOCATION
2011-01-20 02:41:53.688 TestMemoryLimit[32550:a0f] creating 1000 objects
2011-01-20 02:41:53.813 TestMemoryLimit[32550:a0f] *** -[DataItem setString:]: The operation couldn’t be completed. (OSStatus error -1750.) (error -1750)
2011-01-20 02:41:53.957 TestMemoryLimit[32550:a0f] *** -[DataItem setString:]: The operation couldn’t be completed. (OSStatus error -1750.) (error -1750)
INFINITE MEMORY ALLOCATION LOOP AT THIS POINT. HAVE TO KILL APPLICATION TO STOP ITS EXECUTION
-- Dave