Ive been working to bring an old app up to cocoa for a while and its really working great now. Except for the fact that over the course of a few days of running I gain about 200meg of allocation and the app stops responding to anything at all. Under Carbon this app could, and did, run for 6 months or more at a time without any problems or memory growth issues. I have verified through the runtime object that I am leaking no objects that it can track. I am doing no allocation directly with the system or any such thing with it. The memory usage just grows and grows under cocoa where it did not under carbon.
I see plenty of reports here and in feedback of memory leaks, some even alarming, but most are older. Is anybody tracking problems specific to the cocoa implementation? I cant release this with instructions to restart every 2 days when the old version would run without stopping until I would release the next version to people and they had to quit it. Shall I dive into Instruments to try to figure out whats going wrong? Ive not had to do that up until now with anything.
There was a terrible leak in Cocoa / IPCSockets :
Are you using those?
Using Instruments is a good way to find the leaks also.
no IPC sockets, lots of TCP sockets though. Ill install the dev tools on my testing server.
Do you use a lot of dynamically instantiated windows? There’s a memory leak of about 10 MB for each one closed:
Thanks for checking, Travis!
ah, thats interesting, yes I do create windows that way. But in this particular case I can watch the memory leaking away even while the interface of the app is completely static. So that might be leaking too in the app, but its not what Im watching right now.
Ive been running the last 2 hours with the log window display turned off and Im still leaking, so I cant blame styled text handing or the cocoa text field like I really wanted to.
Could it be something not getting a destructor called? I don’t remember the specifics, but I’ve had cases where I had to explicitly call object.destructor when the object is going out of scope.
You should never have to call the destructor function yourself, and probably never should call Destructor yourself.
I’ll see if I can remember what the situation was, but the class I was working on had a destructor in the class, but it never fired… I think I used a “Close” method instead.
Now that I think of it, I think I had a circular reference where I had used addhandler and was calling removeHandler in the destructor, but the destructor didn’t fire if removeHandler hadn’t been called, so I moved removeHandler to a Close method, called when the task completed, and then the destructor was able to fire…
I dont think i have a single destructor method in the entire program. I do use circular references between objects so that they can talk to each other, and in order to break that you have to explicitly nil them out when the classes are done with each other. I know this is working properly as Ive walked the object list and outputted their counts. Im definitely not leaking regular object references. There are multiple problems going on in my conversion I suspect. When I run leaks against it it outputs al sorts of what are internal xojo generic memory blocks, as well as lots of apple event descriptors. Im not sure that they really are leaks though. I havent changed my apple event handling at all, much of it s done via declares because xojo doesnt have enough native accessors for things to do more than the simplest of scriptable apps and the only change I made was to link to Carbon rather than CarbonLib in the declares. (there is no cocoa apple event support, all cocoa apps must link to the carbon libs to support it) My app becomes unresponsive and strange after just a day or so of running and Im still no closer to figuring it out. There are some serious issues with cocoa. But I cant go back to carbon, so Ill keep slogging through it.
I see after 4 months the status of that is still ‘reviewed’. I always wonder what reviewed really means.
In this case there is a project to reproduce attached… so the status should be either:
- Not reproducible
- More Information Required
To me it seems Reviewed should be only for feature requests…
If allowed for bugs reports, the status ‘reviewed’ should automatically revert to “needs review” after say 2 weeks or a month at most.
Im not certain if this is because of Cocoa. Are you sure there is no Cocoa Apple Event handling? Apple docs tell about installing a NSAppleEventManager in Cocoa
I will read up on those sections, thank you. That would mean abandoning all the built in xojo scripting stuff though as those structures are neither the traditional AEDescs nor objects I can easily convert to xojo classes. But there may be conversion methods hidden in there. My own scripting knowledge is old school from before OSX, and Im still able to get all those same structures from the descriptors, very little has changed at that level. Though there are ways now to do a lot of things with them automatically. At least with a ObjC app. When Ive dived into this in the past Ive never been able to make them overlap in a useful way with a xojo app. I will try again
I wonder how many xojo apps there have been that supported the object model for scripting? Its not easy to do, and there really arent any simple xojo docs for doing more than accepting simple verbs.
I think the memory leaks were due to a difference in non-sent AppleEvents in cocoa and carbon. I havent verified this in a separate project yet for a bug report but Im thinking that upon destruction an appleevent object in xojo may not clear up its event descriptors unless it has been actually sent or received. There were several places I was putting a descriptor into an event and then pulling it out as a different type in order to coerce it without resorting to declares and I believe this was where the leaks were happening. When I added specific calls to release the descriptors by their pointers available from the xojo object the problem stopped. When you receive an apple event you do not have to free either the event descriptor or the reply descriptor, thats handled by the system, but if the event is never sent then you do. That might not be the whole story. If I can duplicate it in a separate project Ill make a bug report.