RE: finalization
You still need to malloc() your memory; however I realize that the allocator can be *really* fast here. But still, you give a lot of the gain back during the mark-and-sweep phase, especially if you also move/compact the memory. As you said, the allocator can be really fast. Most advanced gc will use thread local heap to allocate temp objects, so we don't even have to sync or membar. The mark-and-sweep is ok for small heap, 1MB. For large heap, we can use concurrent gc, multi-threaded gc, multi-heap. Normally large heap implies SMP, so we have some cpu power to steal to do expensive gc. The big gain only comes in when your program is small/quick enough to actually finish before the GC kicks in the first time (think CGI). In that case you just discard the whole heap instead of doing a proper garbage collection (unless of course someone thought they could still do something inside a finalizer during global destruction and you still need to finalize every other object on your heap :). As I said, the finalization should be discouraged. It is application's problem if it uses extensive finalization, just like an application uses bubble sort instead of qsort, there is not much we can do here. That is one of mistakes of Java. Java promises too much. To do so, Java carries significant overhead to fullfill its promise. For example, Java has 6+ different types of weak reference, including finalization reference. There are very few people in the world can understand the difference. What is the point to have them just for those smart but few people. Don't even dream of accessing Perl scalars simultaneously from multiple threads without some kind of locking. That is the problem of Perl. In Smalltalk, every primitive object is immutable -- Integer, Float, Fraction, Symbol. The String, Array, ByteArray have fixed size. So there is no need for any synchronization. If you want to mess up your Array using MT, just do it. In the end, you will get a messy array, but you can not hurt the system/runtime in anyway. You want a modifiable buffer? Get a StringBuilder object and lock it on every access. That is one of stupid design of Java. If I need sync, I can do it myself. Why StrinBuffer, Vector, Hashtable, XXXStream sync on every access? Stupid. If I want to have a multi-read data structure, I have to write my own. What is the point??? Hong
Re: finalization
On Tue, 28 Aug 2001, Sam Tregar wrote: Well, there's the Perl 5 reference counting solution. In normal cases DESTROY is called as soon as it can be. Of course we're all anxious to get into the leaky GC boat with Java and C# because we've heard it's faster. I wonder how fast it is when it's halfway under water and out of file descriptors. GC has nothing to do with finalization. Many people want it to, and seem to conflate the two, but they're separate. Dead object detection and cleanup doesn't have to be tied to memory GC. It won't be in perl 6. The perl 6 engine will guarantee whatever cleanup/finalization order and timliness that Larry puts into the language definition. That's not a problem. FWIW, going from a manual memory management scheme to a GC scheme is generally a good-sized performance win. Talk to the GCC people if you don't believe that. Dan
Re: finalization
On Tue, 28 Aug 2001 21:07:03 -0400 (EDT), Sam Tregar [EMAIL PROTECTED] wrote: On Wed, 29 Aug 2001, Jeremy Howard wrote: The answer used in .NET is to have a dispose() method (which is not a special name--just an informal standard) that the class user calls manually to clean up resources. It's not an ideal solution but there doesn't seem to be many other practical options. Well, there's the Perl 5 reference counting solution. In normal cases DESTROY is called as soon as it can be. Of course we're all anxious to get into the leaky GC boat with Java and C# because we've heard it's faster. I wonder how fast it is when it's halfway under water and out of file descriptors. With GC, it is of course again the duty of the programmer to make sure the resources are freed on time: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpapndx/html/_cor_finalize_and_dispose.asp http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguidnf/html/cpconcleaningupunmanagedresources.asp C# has some syntactic sugar to make this a little more convenient to use: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csspec/html/vclrfcsharpspec_8_13.asp Having to do explicit resource management is a real pain when you are used to Perl 5's reference counting. :) BTW, the lure of GC over refcounting is *not* the speed (it is only slightly faster). The advantage is that it takes care of circular references. And it can remove sandbars in your heap for long running processes. It is also supposed to make your programs more robust because you don't have to bother with keeping your reference counts rights. But it has a ton of its own problems with resource management, so I'm not convinced there. -Jan
Re: finalization
On Tue, Aug 28, 2001 at 09:07:03PM -0400, Sam Tregar wrote: Well, there's the Perl 5 reference counting solution. In normal cases DESTROY is called as soon as it can be. Of course we're all anxious to get into the leaky GC boat with Java and C# because we've heard it's faster. I wonder how fast it is when it's halfway under water and out of file descriptors. Speaking purely for myself, I'd rather have a non-refcounting GC because I'm rather tired of going through elaborate tricks to avoid ever creating circular data structures. - Damien
Re: finalization
Sam Tregar wrote: On Wed, 29 Aug 2001, Jeremy Howard wrote: The answer used in .NET is to have a dispose() method (which is not a special name--just an informal standard) that the class user calls manually to clean up resources. It's not an ideal solution but there doesn't seem to be many other practical options. Well, there's the Perl 5 reference counting solution. In normal cases DESTROY is called as soon as it can be. Of course we're all anxious to get into the leaky GC boat with Java and C# because we've heard it's faster. I wonder how fast it is when it's halfway under water and out of file descriptors. I don't think speed is where the interest is coming from. GC should fix common memory problems, such as the nasty circular references issue that has caught all of us at some time.
Re: finalization
On Tue, 28 Aug 2001 19:04:20 -0700, Hong Zhang [EMAIL PROTECTED] wrote: Normally, GC is more efficient than ref count, since you will have many advanced gc algorith to choose and don't have to pay malloc overhead. You still need to malloc() your memory; however I realize that the allocator can be *really* fast here. But still, you give a lot of the gain back during the mark-and-sweep phase, especially if you also move/compact the memory. The big gain only comes in when your program is small/quick enough to actually finish before the GC kicks in the first time (think CGI). In that case you just discard the whole heap instead of doing a proper garbage collection (unless of course someone thought they could still do something inside a finalizer during global destruction and you still need to finalize every other object on your heap :). On MP machine, ref count is really slow, because of the atomic instructions, which are very slow. I measured the atomic x86 instruction such as LOCK INC DWORD PTR [ECX]; long time ago. I believe each instruction takes about 10 to 30 clock cycles. Don't even dream of accessing Perl scalars simultaneously from multiple threads without some kind of locking. To keep their internal caching behavior consistent, you'll need to lock them for even the most simple operations (see the failure of the Perl 5.005 thread model). But even if you give up the caching behavior, what about strings? Atomic updates, eh? Welcome to the world of immutable strings. Just allocate a new string every time you need to modify it and update the string reference atomically. You want a modifiable buffer? Get a StringBuilder object and lock it on every access. :) We could just as well switch to Java or C#. -Jan