Re: dealloc and scarce resources
Re: dealloc and scarce resources
- Subject: Re: dealloc and scarce resources
- From: James Merkel <email@hidden>
- Date: Wed, 29 Jun 2011 22:38:09 -0700
On Jun 29, 2011, at 9:47 PM, Quincey Morris wrote:
On Jun 29, 2011, at 17:43, James Merkel wrote:
"You should typically not manage scarce resources such as file
descriptors, network connections, and buffers or caches in a
dealloc method. In particular, you should not design classes so
that dealloc will be invoked when you think it will be invoked.
Invocation of dealloc might be delayed or sidestepped, either
because of a bug or because of application tear-down.
Instead, if you have a class whose instances manage scarce
resources, you should design your application such that you know
when you no longer need the resources and can then tell the
instance to “clean up” at that point. You would typically then
release the instance, and dealloc would follow, but you will not
suffer additional problems if it does not."
In my code I close a file in the dealloc method -- so I guess
that's a file descriptor. I opened the file in the init method, so
it seemed logical to close it in the dealloc method.
It's only logical to close the file descriptor in dealloc if it's
not a scarce resource. The word "scarce" is vital to this question.
Here's a simple (though contrived) example. Suppose you have a loop
that's compressing image files. In each iteration of the loop, you
open one file for reading and create a new file from it. Let's
suppose you've invented objects to represent the source and
destination files, and each of these object contains a file
descriptor for its open file. It's not hard to imagine, for example,
that for unrelated reasons your file-reading object ends up in the
autorelease pool. Thus, these objects will build up till the loop
exits.
If you free the file descriptor in dealloc, and you have to convert
100,000 files, you're going to need 100,000 file descriptors,
because you can't recycle file descriptors because dealloc isn't
being called until the end of the whole operation. That obviously
isn't going to work, since the kernel can create only a very limited
number of simultaneous file descriptors.
In this case, the recommended solution is to give your object a
'releaseResources' method that will free up its file descriptor.
This is the scenario that the above warning is talking about. Note
that if scarcity isn't an issue, if there could be as many
simultaneous file descriptors as you choose to create, then this
pattern isn't necessary***.
In real life applications, causes of deferral of dealloc can be
really hard to figure out deterministically. Thus it can be hard to
know whether you *need* a 'releaseResources' pattern or not. That's
why the recommendation is couched in terms of such general
applicability. [What the warning doesn't say, though, is that the
opposite problem exists too. It can be *very* hard to determine when
to call 'releaseResources', a problem which carries over into the GC
world too.]
Also, not to be facetious, if I have a bug in my code, wouldn't I
fix it?
I think it's referring to the kind of bug where the object is
lifetime is extended by an inscrutable chain of dependencies. If
your design uses an implicit release-resource-on-dealloc pattern, it
can be very hard to work out where to intervene, so the bug may be
for all intents and purposes unfixable.
Granted, at application tear-down, if the file is still open, it
won't be closed because dealloc won't be called. But again that
comes under the heading of a bug in the code. So I don't understand
this injunction.
Actually, at application tear-down, things like file descriptors are
irrelevant, because they're destroyed automatically with your
process. However, there are things with more global visibility, such
as a system-wide cache, or a network login, that destruction of your
process may "leak". So, application tear-down tends to be the site
of fewer problems, but resource management is still something that
needs to be thought through.
***Actually, it may be necessary even then. *Your* application might
not care if the file descriptors aren't freed until much later, but
you might also be preventing other applications from gaining
exclusive access to the files for some other purpose, so you'll lock
out such applications possibly for hours. This is still a case of
scarcity, just a different kind of scarcity.
Ok, thanks. For what I'm doing file descriptors are not a scarce
resource. Also, I didn't know file descriptors are destroyed at
application tear-down.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden