POV-Ray : Newsgroups : povray.off-topic : Thinking about Languages again : Re: Thinking about Languages again Server Time
1 Oct 2024 18:32:28 EDT (-0400)
  Re: Thinking about Languages again  
From: Darren New
Date: 28 Mar 2008 14:40:58
Message: <47ed49ca$1@news.povray.org>
Warp wrote:
>   The OS may help the GC system when we are talking about OS resources.
> However, it can't help when we are talking about resources within the
> program itself. (For the sake of example, let's assume that the program
> uses its own "file handles" instead of the ones provided by the system.
> It doesn't need to be something related to physical files per se.)

Most systems I've seen deal with this pretty easily, too.

>   The problem is not leaving file handles open when the program exits.
> The problem is opening more and more file handles without closing the
> old ones: In most systems at some point the OS will put a limit to this
> and refuse to give any more file handles. At this point the program will
> malfunction, and finding and solving the cause can be quite difficult.

And this is where I say that the OS support helps a bunch. If the OS 
garbage-collects the file handles like it GCs memory, it's fine.

That is, saying "at some point you run out of file handles and crash" is 
no more a problem with "proper" GC than saying "at some point you run 
out of memory and crash".  Either you're actively using too many file 
handles, or they get cleaned up and collected.

Not in most desktop OSes today, mind.

>   Usually this is a sign of a bug: Some code somewhere is "leaking".
> Not all unused file handles are being closed.
>   However, with GC, where there's delayed object destruction, it might
> not be a bug per se, but a consequence of GC.

At which point the GC runs, the files get closed, and you're golden. No 
more problematic than the fact that memory cleanup is delayed until you 
run out of memory.

>> No, the OS closes the files for you.
> 
>   It can't close them if it sees that they are in use: Some live objects
> are holding the file handles (because these objects have not been
> properly destroyed).

Then it's not safe to close the files. Either they're accessible, in 
which case it's no different than using up memory, or they're not 
accessible, in which case the OS could (in theory) GC the handles for 
you just as easily.

>   Of course one thing the OS might try is to tell the GC to make a sweep
> to see if that frees any file handles (does any OS actually do this?).

That's what I was describing. And yes, there are any number of 
environments that will do this sort of thing. It is, for example, how 
Smalltalk originally worked back when it was its own OS.

> However, as I said, this will work only with system resources.

If you have a resource that's limited in your code, you write a simple 
bit of code that says "if I try to allocate an X, and there are no X's 
left, trigger a garbage collection, then try it again, once."

Just like if you run out of memory.

>   This assumes that the main loop is advanced before the amount of leaked
> resources grows too large. It can alleviate the problem, but it's not a
> guarantee.

True.

>   (And if the main loop is executed very often, eg. thousands of times
> per second, wouldn't it cause overhead to call the GC each time?)

Or call it once a second, or once every N times thru the main loop, or 
whatever.

>> And of course anything that allocated stuff on the heap has this sort of 
>> problem anyway, unless you wind up essentially writing your own GC anyway.
> 
>   There are alternatives to GC which call destructors immediately when
> the objects go out of scope. For example, if I'm not completely mistaken,
> objective C uses reference counting.

The problem with reference counting is twofold: it doesn't work reliably 
if the bits your counting can point to themselves (directly or 
indirectly), and the reference count has to be at least as big as the 
number of possible pointers.

The former is a problem if you want it to be general. Reference-counting 
strings or file handles isn't much of a problem. Reference-counting 
arbitrary user data structures (like doubly-linked lists) doesn't work. 
The firefox people are starting to realize this.

The latter is a problem if you want to deal with (as you are fond of 
using as an example) pixels. Do you really want a 32-bit reference count 
on every 32-bit pixel?

>   Someone mentioned that in C# it's possible to tell for an object that
> it should be destroyed immediately when it goes out of scope (but otherwise
> regular GC is performed). That sounds like a good solution to me. You get
> the best of both worlds.

In C#, you have a "using" statement, which creates a new scope within 
which the object is allocated, and which calls the "Dispose" method when 
you leave the scope. Basically, prettiness for try/catch/finally.

I've seen Java research that does this for *all* objects the compiler 
can prove doesn't escape the scope.  Of course, if you pass a reference 
to the object to some other method, you lose that ability.

>> Only naive GC.  Of course, sophisticated GC needs support throughout the 
>> system. Some systems have this.
> 
>   There's no way the OS can know about the program's internal resources
> even if it cooperates with the GC engine to handle system resources.

What sort of "internal resource" are you talking about? Can you give an 
example?

>> Other systems don't have this sort of problem at all, in that files are 
>> memory resources just like "in-memory" structures, so going out of scope 
>> deletes the file just like you'd expect.
> 
>   Don't stick to the file handles in particular. It was just an easy to
> understand example.

Certainly. It's just an example, but one easy to generalize. What are 
some other examples you've encountered?

AFAICT, there are three bits:
1) Internal pre-allocated things, like a threadpool or buffers in a 
certain kind of memory or something, that the OS can't help with.
2) External things that can get cleaned up reliably, like open file handles.
3) External things that can't get cleaned up reliably, like file data.

#1 is easy to take care of - invoke the GC if it runs out and have the 
"Dispose" free the resource.

#2 can be dealt with like #1 if you have an OS or other virtual layer in 
between (like a VM) cooperating.

#3 is difficult to deal with without extensively labeling what you create.

-- 
   Darren New / San Diego, CA, USA (PST)
     "That's pretty. Where's that?"
          "It's the Age of Channelwood."
     "We should go there on vacation some time."


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.