From: Gustav M. <grd...@gm...> - 2008-08-26 12:36:22
|
On Mon, Aug 25, 2008 at 6:22 PM, Daniel Rogers <da...@ph...> wrote: > > On Aug 25, 2008, at 8:29 AM, Gustav Munkby wrote: > >> I'm implementing a HOC/Cocoa frontend for >> the Yi editor, and so far it works really well. >> >> I was puzzled about messages concerning >> autoreleasing without a pool in place. After >> some digging I have concluded that the >> problem was that there was no autorelease >> pool in place while finalizers were executed. > > Hmm, there should always be an autorelease pool in place. If you're not > using one of apples built in event loops, you should allocate/deallocate an > autorelease pool in your main method. That being said, not having finalizer > autoreleased objects actually release until the program exits is probably > unacceptable. For the main application there is one main autorelease pool available during the scope of the whole program, and then the run-loop creates a new pool every iteration (according to the documentation). > hmm, are these finalizers being run after the main method exits? If so, > it's actually safe to ignore those warnings. The issue is that the finalizers are being executed in their own thread, and Cocoa needs autorelease pools to be established in each thread. The finalizers are not executed after the application finishes, but rather during Haskell garbage collection. >> I tried wrapping the finalizers in >> withAutoreleasePool which removed the >> messages, but resulted in Yi crashing after >> some time when an autoreleasepool is >> deallocated twice. I can reproduce the >> error, but not predictably. > > I'd really like to understand this error. It would go a long way toward > understanding if this is the "right way." As far as I can tell, that should > work. Yes, that seems reasonable. However, I cannot say that I exactly understand the interaction between Haskell and Objective-C in terms of memory management. >> I then tried wrapping only the actual calls >> to release/dealloc in the finalizer, and with >> quite some testing I have not been able >> to reproduce the above failure. > > While I don't understand why wrapping the finalizers didn't work, and that > bugs me, this is more or less how you are supposed to use autorelease pools. > >> I do not understand why this works, but >> this _is_ in the "Arcane Magic" section >> of HOC, so I guess I should not be too >> surprised. =) > > Autorelease pools work by telling the runtime "I no longer need this object, > but I'm pretty sure someone else is going to want it, so I'll just put a > message in the pool, and go ahead an deallocate the object when the pool is > released." It's essentially a delayed release. It's good practice to > sprinkle your code with new autorelease pools whenever you're allocating > then deallocating a large number of objects so that stuff is actually > released and the memory is freed when you exit that section. Otherwise you > have to rely on the top level autorelease which is probably allocated in (or > close too) your main method. This is a good description of autorelease pools. The one thing left out that is relevant for this discussion is that there is a stack of autorelease pools per thread, and outside the main thread you are not only encouraged, but even required to set up an autorelease pool. >> Is this the right way to fix this problem? > > Arguably, the right way is to side step the issue entirely and use garbage > collected interfaces. Otherwise yes, (other than not understanding why > wrapping the entire finalizer didn't work). That is a completely different can-of-worms, which would indeed solve this issue. However, having both Haskell and Objective-C run their own garbage collectors would supposedly require even more "Arcane Magic". > Also, I don't believe dealloc is supposed to require an autorelease pool. > Though someone could always override dealloc and call autorelease and > objective-c expects there to always be an autorelease pool available. I'm quite sure that the normal release message is also not using any pools. >From the looks of the messages produced by Yi, an NSView autoreleases its child views upon receiving a dealloc message. !g |