Slashdot Mirror


Pros and Cons of Garbage Collection?

ers asks: "Most new programming languages are using garbage collection, rather than programmer-controlled memory management. The advantages are obvious: programmers no longer have to worry about forgetting to delete allocated memory, leading to far fewer memory leaks. The disadvantages are often glossed over by programming language designers - aside from the performance issues, predictable memory management can be used for controlling access to files and similar resources, creating safer thread locking code and even providing better error messages. Some programming languages, which usually predictable memory management, can also be made to behave like they are garbage collected - for example, Boost provides various C++ smart pointer classes. So, given the choice between garbage collection or manual memory management, which would you choose and why? When using a manual memory management language, when do you consider the performance and syntactic overhead of faked garbage collection to be worthwhile?"

243 comments

  1. C++ basically has it right by keesh · · Score: 2, Insightful

    The C++ model is basically correct. It doesn't treat the programmer like an idiot (which admittedly may be a problem if you have idiot programmers), and it gives you the choice of how to handle memory allocation. The lack of reference-counted pointer in the standard library is a bit of a bitch, but the Boost shared pointer templates will likely make it into C++0x, and it's only a hundred lines of code or so to make your own in the mean time.

    Of course, the C++ model is not perfect either. Lack of virtual and const constructors can be a nuisance (the workaround being the pimpl idiom and a shared pointer), and not being able to use shared pointers to functions without nasty syntactic hackery occasionally breaks the "stuff pretending to be a pointer" illusion. Still, the power it gives over the Java model is definitely worth the occasional bit of extra effort.

    Then again, if you're coding some quick scripting hack rather than a proper program, who cares about memory allocation?

    1. Re:C++ basically has it right by try_anything · · Score: 3, Insightful

      I don't think garbage collection implies treating the programmer like an idiot. The programmer's attention is a finite resource that is often better spent on something other than memory management, especially given that garbage collection performs quite adequately for many programs. A Perl, Java, or Lisp programmer isn't an idiot for not doing his own memory management any more a person who doesn't make his own shoes is an idiot.

    2. Re:C++ basically has it right by Pseudonym · · Score: 3, Insightful
      The C++ model is basically correct.

      On the contrary, the C++ model is basically correct for some applications.

      A "proper program" is programmed in the appropriate language for the job. Sometimes this is a domain-specific language. Sometimes you need the close-to-the-metal-yet-still-maintainable-for-larg e-applications qualities that C++ provides. And sometimes you don't.

      Very few people write web applications in C++, and for good reason. Web servers run at the speed of the network card, not the speed of the L1 cache. Pulling out extra cycles is pointless especially if you lose the maintainability that a general purpose language like C++ provides. And yet you wouldn't call many of these "quick scripting hacks".

      --
      sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
    3. Re:C++ basically has it right by Curien · · Score: 1

      The problem with most garbage-collected languages is that they don't have the concept of a limited-lifetime object. Stacks are a tool, and a damned useful one. We still mostly structure our code in stacks. But the direction of Java and co is to tell the programmer that since he needs some help with non-stack-allocated stuff, well, then he just doesn't get to have use a stack at all. That's just not a useful tradeoff; I'd rather have a proper stack.

      --
      It's always a long day... 86400 doesn't fit into a short.
    4. Re:C++ basically has it right by Spy+Hunter · · Score: 1

      In C# structs are allocated on the stack. But it's almost entirely a performance decision to do so, and doesn't affect object lifetimes as seen by the programmer. For limited-lifetime objects, C# actually has a built-in keyword. It's called using and it works along with the IDisposable interface, regardless of whether your object was allocated on the stack or not. But in a garbage-collected world most objects don't need to have their lifetimes managed, and that's a good thing, not a bad one.

      --
      main(c,r){for(r=32;r;) printf(++c>31?c=!r--,"\n":c<r?" ":~c&r?" `":" #");}
    5. Re:C++ basically has it right by ultranova · · Score: 1

      But the direction of Java and co is to tell the programmer that since he needs some help with non-stack-allocated stuff, well, then he just doesn't get to have use a stack at all. That's just not a useful tradeoff; I'd rather have a proper stack.

      Um... Just where do you think the method-local object references are stored to ?-) And anyway, the decision on whether or not to store the fields (data) of an object to stack or to heap is completely mechanical: if you pass references to other functions, the object needs to go to heap; otherwise, it can go to stack.

      Since this is a purely mechanical decision, it is best left for the compiler/runtime to deal with, freeing human attention for more important tasks, resulting in faster code with less chances of error - no possibility of changing the function so that the object gets passed out of it but forgetting to change the allocation type...

      --

      Forget magic. Any technology distinguishable from divine power is insufficiently advanced.

    6. Re:C++ basically has it right by Oscaro · · Score: 2, Insightful

      I don't think garbage collection implies treating the programmer like an idiot. The programmer's attention is a finite resource that is often better spent on something other than memory management.

      I have mixed feelings regarding garbage collection. Sure enough when people are learning how to write programs, it's far better to use a language garbage collection, so that one has to really understand what's happening. Also, having to manually keep track of your data can lead to cleaner code (I know one can write clean code in Java, too, but given the "lazy" nature of people (or the strict timeframes) this is really not too common).

      On the other hand, your argument is painfully valid. The programmer's attention (and time) is a finite (and scarce) resource.

    7. Re:C++ basically has it right by Westley · · Score: 2, Informative

      In C# structs are allocated on the stack.

      No, they're allocated "inline" with the variable (if there's one involved) or on the stack if they're part of an intermediate expression. The mantra of "struct => stack" is one which has confused many people in my experience. See http://www.pobox.com/~skeet/csharp/memory.html for more details. (I'm only picky about this because of the confusion that this has caused.)

      For limited-lifetime objects, C# actually has a built-in keyword. It's called using and it works along with the IDisposable interface, regardless of whether your object was allocated on the stack or not.

      Calling Dispose doesn't change the lifetime of your object (well, it might suppress finalization). It's to do with releasing resources *other than* the memory taken up by your object itself.

    8. Re:C++ basically has it right by Spy+Hunter · · Score: 1

      Right, using limits the lifetime of your allocated resources, not the object itself; but that allows it to fill the same role as a stack-allocated variable in C++ (only without the possibility of passing a dangling pointer to the stack out of your function). And structs are usually allocated on the stack but can be part of objects and even boxed. I'm aware of the distinctions but didn't take the time to lengthen my post with all the details.

      --
      main(c,r){for(r=32;r;) printf(++c>31?c=!r--,"\n":c<r?" ":~c&r?" `":" #");}
    9. Re:C++ basically has it right by try_anything · · Score: 1

      Sure enough when people are learning how to write programs, it's far better to use a language garbage collection, so that one has to really understand what's happening.

      This is something that I have yet to figure out. On one hand, I think it's important for programmers to understand the machine that their code runs on. On the other hand, I wonder if it's possible for a programmer to achieve a useful level of understanding of what's "really happening." To be useful, a model must be simple enough to enable reasoning, be accurate enough to provide useful answers, and specify its limitations. How many people have such a model of, say, a Xeon processor or their language's implementation of memory management?

      I think it's more important for beginning programmers to learn to program the abstract machine that their language presents to them, rather than the "real" or "bare metal" machine they are taught to believe in. These abstract machines are specified in language definitions and guaranteed by language implementers, so they are real enough to be depended on and reasoned with. Garbage collection or not, that makes them much more real than a programmer's imagination of how a program gets implemented by the platform.

    10. Re:C++ basically has it right by angel'o'sphere · · Score: 1

      This is not correct:

      under .NET you can chose wether you want to allocate an obejct on the stack: short term allocation
      or wether you want to allocate it on the ehap. long time allocation.

      Disadvantage: this is in most cases class based, so all objects of a given class are value objects and allocated on the stack, or "reference" objects and alloated on the heap.

      In Java the GC is a generational GC, so it automatically distinguishes between short and long time allocatin by propagating young uncollected objetcs to older generation heaps.

      Having both: true object based differenciation between short term and long term allocations is pretty difficult. Look at C++ .NET their attempt to achieve it.

      Just consider yourself: passing around references to objects, which are either on stack or on heap, then such references are stored in other objects, which are either on the stack or heap again. Its pretty hard to get a reliable modle of such a situation, e.g. you can't drop a "short term" object which is on the stack "and should be dropped" but is referenced by another object from the heap, so it should not be dropped.

      angel'o'sphere

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    11. Re:C++ basically has it right by /ASCII · · Score: 1

      The thing is, it is _very_ common to pass a reference to an object to another method, so nearly all objects are allocated on the heap. But most methods that take an object reference as an argument don't actually keep any copies of it after the method returns, meaning many objects that are allocated on the heap using your 'purely mechanical decision' could actually be allocated on the stack. But figuring that out requires escape analysis, which is both expensive and error prone, which is why Java is only getting it now, in the latest preview releases of Suns JDK.

      --
      Try out fish, the friendly interactive shell.
    12. Re:C++ basically has it right by /ASCII · · Score: 1

      Thinking some more on this subject, I realized that all objects have a reference to them passed to another method (the constructor) on creation, so using your simple rules, not a single object would ever be allocated on the stack. And there is no way around that without using at least some simple escape analysis, since a constructor may pass on a reference to the newly created object to some other method.

      --
      Try out fish, the friendly interactive shell.
    13. Re:C++ basically has it right by CloakedMirror · · Score: 1
      I think it's more important for beginning programmers to learn to program the abstract machine that their language presents to them, rather than the "real" or "bare metal" machine they are taught to believe in. These abstract machines are specified in language definitions and guaranteed by language implementers, so they are real enough to be depended on and reasoned with.

      I would tend to agree with this statement, except for one critical area; debugging. The younger programmers I deal with often are lacking in understanding the underlying "machine." When one lacks an understanding of the way the "machine" operates, it makes it difficult to find the more esoteric bugs that find their way into code. To neglect teaching basic concepts, such as memory management, means that programmers miss out on some of the underlying principals that can make their jobs easier.
      --
      Evolutionary thinking will move you down the road, revolutionary thinking will put you on a new road!
    14. Re:C++ basically has it right by ultranova · · Score: 1

      Thinking some more on this subject, I realized that all objects have a reference to them passed to another method (the constructor) on creation, so using your simple rules, not a single object would ever be allocated on the stack.

      True. However, you can simply analyze the constructor too - it only needs to be done once per constructor. And you could recurse trough all the methods the object gets passes to, altought this might be less usefull since the exact same calling sequence is unlikely to repeat often enough to ofset the initial cost of recursing.

      And there is no way around that without using at least some simple escape analysis,

      Checking if a method passes a reference to the object it created to other methods is simple escape analysis. That's what escape analysis means - checking if a reference escapes the scope. So no, there's no way out of using escape analysis if you want to use stack; the only question is who does it, computer or you. And the JVM can perform this analysis at runtime, when it actually sees what methods call which, while you as a programmer don't neccessarily know that - your code could be expanded or reused by someone else.

      since a constructor may pass on a reference to the newly created object to some other method.

      Which has a high chance of creating nasty synchronization bugs - letting references to the object being constructed escape from the constructor to where other threads might see it means that they can call methods on half-constructed object, leading to all kinds of fascinating problems.

      --

      Forget magic. Any technology distinguishable from divine power is insufficiently advanced.

    15. Re:C++ basically has it right by jgrahn · · Score: 1
      The programmer's attention is a finite resource that is often better spent on something other than memory management, especially given that garbage collection performs quite adequately for many programs.

      Yes, but note that you don't have to bother much with memory management in C++ either, these days. I maintain really sucky C++ code for a living, and memory management is the least of my problems. (People using C++ as C and/or Java are my biggest problems.)

      A Perl, Java, or Lisp programmer isn't an idiot for not doing his own memory management any more a person who doesn't make his own shoes is an idiot.

      True, although the languages which I like in that category (Perl, Python) tend to use reference counting rather than Java-ish garbage collection ...

    16. Re:C++ basically has it right by Pseudonym · · Score: 1

      Garbage collection is a continuum between raw C with free and malloc at one end and completely automatic concurrent real-time cycle-friendly scavenging at the other. Just because it's reference counting doesn't mean it's not garbage collection, especially if it's done behind the scenes.

      Actually, there is one aspect of modern C++ with smart pointers that I like. There is a huge semantic difference between this:

      void f1(Foo* p_f);

      and this:

      void f2(boost::shared_ptr<Foo>& p_f);

      In this code, f1 is explicitly advertising in its type signature that it does not intend to manage the lifetime of the object passed in, where f2 is explicitly advertising that it may. This is valuable documentation, which you don't get for free in a language with automatic GC. (Though, to be fair, in a pure language, such as a functional or logic language, it makes no difference because data objects are not mutable.)

      --
      sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
    17. Re:C++ basically has it right by Gravis+Zero · · Score: 1

      unfortunately even if you are a idiot programmer using garbage collection, you can still take down a system by not deallocating often enough. it's the reason the java server for the census bureau crashes out daily. time to stop hiring idiot programmers and start using manual memory (de)allocation.

      --
      Anons need not reply. Questions end with a question mark.
  2. Depends by Apreche · · Score: 4, Insightful

    It depends on what you are trying to make, duh.

    If you are trying to make something where performance is important, like a 3d game, then manage memory yourself. If you are making a simple business application where reliability and security are important, use garbage collection. If your program uses lots of RAM and you need every last drop either find an expert at RAM management to get every last bit or use garbage collection if your programmers are not so awesome.

    And so on and so on...

    --
    The GeekNights podcast is going strong. Listen!
    1. Re:Depends by Anonymous Coward · · Score: 0

      If reliability is the goal, surely you'd want full control over resource allocation? Garbage collection is utterly unpredictable...

    2. Re:Depends by Anonymous Coward · · Score: 0

      GC -> you are guaranteed memory will be freed eventually if not referenced

      full control -> you are guaranteed some programmer will forget to free something eventually

      not sure how you can call the former unpredictable...

    3. Re:Depends by ivan256 · · Score: 2, Insightful

      Actually, it seems to me that if you want reliability, maintainability, and perhaps most important, debugability, you want to manage your memory yourself.

      When debugging a program with a leak (Yes, garbage collected programs have leaks too, they're just nastier, because they don't look like bugs because a reference is persisting somewhere.) if memory is program managed, finding the leak is a deterministic process. You're guaranteed success in a well-defined, and finite amount of time (The amount of time it takes to reproduce the leak plus the amount of time it takes to build the application, plus the amount of time it takes to get a basic understanding of the application structure). When you're debugging a leak in a memory managed environment, you're limited to the tools provided, which are pretty much universally not good at finding the worst kinds of leaks, because to the tools your leak looks like perfectly valid utilization. You're really doomed if your leak is in a third party library. You may never track it down, or even find the culprit. (Any Jakarta users out there?)

      Sure, languages without garbage collection may be more prone to leaks, but I'd rather have more leaks that I can fix, than fewer leaks that I can't...

      Not that garbage collection doesn't have it's place. If you're application is complex enough though, allocating your own memory is the least of your worries.

      If your program uses lots of RAM and you need every last drop either find an expert at RAM management to get every last bit

      I don't care what kind of programmer you are, you should have a good foundation in certain things. Data structures, obviously. Discrete logic. Algorithmic complexity, including the ability to read and understand Big O notation (wspecially true of java programmers)... And a complete knowledge of basic memory management. Even if you're going to use garbage collection. Without these things, you're doomed to write poor programs. If you don't understand how a utility library works, you shouldn't be using it.

    4. Re:Depends by swillden · · Score: 4, Insightful

      It depends on what you are trying to make, duh.

      Agreed.

      If you are trying to make something where performance is important, like a 3d game, then manage memory yourself.

      It's not that simple.

      In most cases, the total run-time cost of garbage collection is lower than that of malloc/free memory management, at the cost of higher on-average memory usage (which can obviously destroy performance if you end up having to swap). On the other hand, application-tuned manual memory management using pooled allocation is generally faster than GC. Whether or not pooled allocation increases memory usage as much or more than GC depends on many things. Another consideration is that although GC often consumes less total CPU cycles than malloc/free, non-incremental collectors tend to use those cycles in big batches, which can produce GC 'pauses'. That's bad for some applications. Incremental collectors can minimize this effect, but only with some cost in CPU cycles.

      Then there's also the whole issue of the effect of different approaches on the multi-tiered memory caching in modern systems.

      In short: yes it depends on what you're trying to make. No, it's not nearly as simple an analysis as you describe.

      Not only that, in practice other constraints usually dictate the choice anyway. Using GC generally means using something like Java, C#, Python, etc. rather than C or C++, which brings in a whole raft of other considerations, many of them more important than the memory management discussion. Platform, target environment and libraries will often dictate language selection, which will dictate much of memory management approach.

      --
      Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.
    5. Re:Depends by toddbu · · Score: 2, Insightful
      not sure how you can call the former unpredictable...

      Because in many systems that employ GC, they try to free resources on background threads for performance. The problem is that a resource can be held way beyond what the developer expects, and suddenly they get faults happening in totally unrelated sections of code. I've seen it a million times before, and I personally think that it's one of the biggest weaknesses of the CLR. When a function is done with a resource, clean it up right then and there. At least then you'll have some chance of figuring out what's going wrong.

      Oh, and for all you folks that say that nothing should ever crash in cleanup, think again. Microsoft will tell you that publically, but there are lots of things that you can do to make an app crash in GC, like manually cleaning up some stuff yourself before exiting the function. The GC routine will get very confused trying to clean up a partially cleaned up object.

      --
      If you don't want crime to pay, let the government run it.
    6. Re:Depends by alienw · · Score: 2, Insightful

      Are you joking? A large fraction of bugs in software are due to mismanaged memory. This is one of the main reasons Java apps have much, much better reliability than C++ ones. Without a garbage collector, many types of (perfectly legitimate) structures become very difficult to use. When you create objects in one module and give them to someone else, you create bugs. Then you have to come up with some kind of reference counting system anyway.

      Yes, garbage collected programs have leaks too, they're just nastier, because they don't look like bugs because a reference is persisting somewhere.

      That's not a leak, it's sloppy programming. Are you saying it is better to leave stray pointers around and potentially crash the program or corrupt data?

    7. Re:Depends by cgenman · · Score: 1

      Actually, while you may want to make certain parts of you game in C for speed purposes, you're probably going to want a simple scripting engine that everyone from designers to artists can use with little additional training... And you can't expect them to deallocate variables intelligently.

    8. Re:Depends by Spy+Hunter · · Score: 3, Insightful
      I fail to see how following a chain of references to a memory hog is harder than finding a memory leak which has nothing pointing to it at all. In a garbage-collected application, with a proper debugger and profiler you should not have any trouble figuring out exactly what's taking up every byte of your memory, and once you've done that you can easily figure out who has the references to it. I recommend you take a look at Microsoft's awesome CLR profiler; I'm sure a similar tool exists for Java but it may not be free.

      It is just as easy to keep references to unneeded objects in C++, so C++ can have the same types of so-called "hard to debug" leaks you blame on garbage collection. But on top of that, if you have a true memory leak, C++ doesn't even tell you what's stored in all that leaked memory. You'll just have to trace back to find the last guy anywhere in the code who threw away a pointer without deleting it, and it could easily be very tough to figure out. And C++ doesn't have a magical solution to leaks in third-party libraries either.

      --
      main(c,r){for(r=32;r;) printf(++c>31?c=!r--,"\n":c<r?" ":~c&r?" `":" #");}
    9. Re:Depends by archeopterix · · Score: 2, Interesting
      Actually, it seems to me that if you want reliability, maintainability, and perhaps most important, debugability, you want to manage your memory yourself.
      And try to pinpoint which of the hundred thousand totally unrelated functions has modified my data because it happens to use a bad pointer?

      I had to debug a C program that started crashing after an unused variable declaration had been removed. The reason? - a dangling pointer.

      The program was compiled without any optimization, so the memory for the variable had still been allocated (in spite of the var being unused), which shifted the other variables to that the dangling pointer had missed them. After deleting the unused var, the pointer (used totally elsewhere) damaged the data.

      Managed memory gets you rid of this kind of problems. Or, at least, confines them to external libs written in non-managed languages.

    10. Re:Depends by Anonymous Coward · · Score: 0

      You are talking C, the parent was talking C++.

      There is an important difference, destructors + the stack.

      If you make proper use of encapsulation, auto_ptrs, etc, these bugs are a lot less common than in C.

    11. Re:Depends by Taladar · · Score: 1

      You seem to be under the impression that all GC languages are made by Microsoft. However those are just a small fraction. All scripting languages as well as most functional (and functional-related such as Lisp) languages use GC and seem to work pretty well with it. I never heard of anyone having a GC-related debugging problem (as in real bug, not performance) for programs written in one of those languages.

    12. Re:Depends by Mr.+Slippery · · Score: 2, Interesting
      When you create objects in one module and give them to someone else, you create bugs.

      No, the caller of your module creates a bug when they fail to free the object that you have clearly defined in the interface to be their responsibility. It's no different than any other violation of an interface condition. (If you don't clearly define your interfaces, then yes, you have of course created a bug.)

      That's not a leak, it's sloppy programming.

      Are you saying that leaks are not a form of sloppy programming? You've either failed to free things you knew needed to be freed (your sloppiness) or you've failed to know which things needed to be freed (which could be your sloppiness or someone elses').

      --
      Tom Swiss | the infamous tms | my blog
      You cannot wash away blood with blood
    13. Re:Depends by ivan256 · · Score: 2, Insightful

      so C++ can have the same types of so-called "hard to debug" leaks you blame on garbage collection

      I said they become more difficult to debug because of garbage collection. They're certainly not caused by the garbage collection. They're caused (usually) by poor programming.

      Garbage collection is a tool. It makes your job as a programmer easier, but it does not free you from the need to understand things like scope. Just because you don't have to worry about the mechanics of managing your memory, you still need to understand how it works, or you are going to write crappy code. Code that leaks.

      But on top of that, if you have a true memory leak, C++ doesn't even tell you what's stored in all that leaked memory.

      That's because you don't need the programming language to tell you that. There are plenty of ways you can make it easy to tell what's in your leaked memory. And then when you're done debugging, you can turn them off and reduce your memory footprint.

    14. Re:Depends by ivan256 · · Score: 1

      There are so many poor practices involved in that situation you just described that I don't even know where to begin.

      There are dozens of simple rules you can follow when you write C code, any one of which would have prevented that problem. Either way, having your memory managed for you doesn't imply that you don't have access to the raw data anyway. Protection is only enforced in some languages.

    15. Re:Depends by Arandir · · Score: 1

      It depends on what you are trying to make, duh.

      It would be nice if more people believed this, but unfortunately there's language religion involved. When the preacher sermonizes on the glories of your chosen language, and the choir sings rhapsodic hymns to its built in GC, then you're going to view every other language out there as heretical, apostate or heathen.

      --
      A Government Is a Body of People, Usually Notably Ungoverned
    16. Re:Depends by Breakfast+Pants · · Score: 1

      "There are dozens of simple rules you can follow when you write C code, any one of which would have prevented that problem." That doesn't matter if you aren't the one who wrote the original code. The fact is it simply can't happen in a language like Java.

      --

      --

      WHO ATE MY BREAKFAST PANTS?
    17. Re:Depends by alienw · · Score: 1

      No, the caller of your module creates a bug when they fail to free the object that you have clearly defined in the interface to be their responsibility.

      OK, so what if I want to give the same object to 2 different modules? These things aren't always trivial. What if an exception occurs somewhere and you don't have a chance to clean up properly? Memory leaks are not usually caused by sloppy programming. Allocating and deallocating memory properly can get very complicated, and most truly complicated programs have to use smartpointers and other primitive forms of GC to manage memory.

      Are you saying that leaks are not a form of sloppy programming?

      Leaks are bugs. Once you lose a pointer to an allocated object, you can't free the memory anymore. If you delete an object that is still in use, you will cause the program to crash. Keeping objects around for longer than you need them is inefficient, but it is not a bug, and will not generally cause the program to behave incorrectly. Any decent profiler should be able to show you how much memory each part of your program uses, so these inefficiencies are easy to correct.

    18. Re:Depends by toddbu · · Score: 2, Insightful
      You seem to be under the impression that all GC languages are made by Microsoft.

      Not at all. I was just citing the CLR as one example since it's fairly widely used. You'd also think with all that we've learned about GC on a background thread that Microsoft would have done something different for their new programming environment, but that wasn't the case.

      I never heard of anyone having a GC-related debugging problem (as in real bug, not performance) for programs written in one of those languages.

      Do those languages perform GC in the background, or do they free resources as they're no longer needed? Do they access external resources such as a database, where holding resources can exhaust the available pool, thereby creating artifically scare resources (which is a bug in my book)?

      Most languages that do GC on a background thread have trouble under heavy load because they end up spending lots of time trying to figure out whether they should or shouldn't be cleaning up memory. Also, because most GC systems aren't aware of the difference between physical and virtual memory, they can induce high levels of page faulting even though they think that there's plenty of memory available. Any system that performs GC in the background is going to suck in a high performance environment.

      --
      If you don't want crime to pay, let the government run it.
    19. Re:Depends by ivan256 · · Score: 1

      The fact is it simply can't happen in a language like Java.

      There are a lot of things that can't happen in a language like Java. Some of them are considered features in some circumstances. At least you have the option to manage your memory or have it managed for you in C, instead of being stuck with one way or the other.

    20. Re:Depends by Spy+Hunter · · Score: 1
      And I meant they don't *become* more difficult to debug because of garbage collection. What garbage collection does is *fix* all the memory leaks which *aren't* hard to debug, which is a completely different thing. And furthermore I dispute your claim that those types of leaks acually are harder to debug; in fact I think it's just the opposite.

      There are plenty of ways you can make it easy to tell what's in your leaked memory.

      ... by doing more work manually. Work you wouldn't have to do if you were using garbage collection.

      --
      main(c,r){for(r=32;r;) printf(++c>31?c=!r--,"\n":c<r?" ":~c&r?" `":" #");}
    21. Re:Depends by Jambon · · Score: 1
      Could someone please explain to me why things like the Linux kernel and Enlightenment are written primarily in C? From what I get in the discussion the performance of GC depends largely on the algorithm used, so is it theoretically possible that a kernel written with GC could be as fast it is now? So, if buffer overflows are such a big deal for exploits, wouldn't this make more sense?

      I don't know much about programming, but I am genuinely curious about this possibility. Could someone shed some light on this?

    22. Re:Depends by Breakfast+Pants · · Score: 1

      Oh, I completely agree. But in a situation with 3rd party libraries it isn't reasonable to demand in C++ that all libraries you link in must use the safety mechanisms you would put in your own code. Granted at the same time you can use 3rd party C++ libraries in java so perhaps it is a moot point.

      --

      --

      WHO ATE MY BREAKFAST PANTS?
    23. Re:Depends by Anonymous Coward · · Score: 0

      Well, read this first:

      http://www.tux.org/lkml/#s15-3

      For the "why" C versus C++.

      Garbage collection is another can of worms. The short answer is because kernel code needs precise control over when allocations and deallocations occur.

  3. Mainly GC but sometimes... by 2starr · · Score: 2, Interesting

    In general I prefer having a GC because most of the time I don't want to have to worry about memory management... there's no need. However, sometimes it would really be nice to have more direct control. Not being a VM expert myself, it seems like it should be possible (though I can imagine the types of problems that would arise) to allow specifying that you're assuming manual memory control either over certain objects or while inside a particular context.

    --

    "Let your heart soar as high as it will. Refuse to be average." - A. W. Tozer

    1. Re:Mainly GC but sometimes... by plover · · Score: 1
      What I don't understand is why they couldn't have written Java (and .NET) so we could have our cake and eat it too.

      For the most part, GC for memory is a good thing. (I do business apps, so the immediate performance of memory typically isn't a problem.) But why couldn't they give us a default "going-out-of-scope" method? I love the whole C++ constructor/destructor idiom because it makes using the native classes for resource management a breeze. Want a class to wrap a file handle? Sure, no problem, we'll close it when you're done with it. A database accessor? Same thing.

      So for the most part, I'm not fussy about when the memory is actually reclaimed by the OS. But for the rest of the resources, I want to be able to micromanage their lifetimes; and I would like to hide that from the consumer of the object. Why do these languages insist on treating GC as an XOR? There's room for both models.

      --
      John
    2. Re:Mainly GC but sometimes... by bckrispi · · Score: 1
      But why couldn't they give us a default "going-out-of-scope" method?

      They did.

      protected void finalize()

      --
      Xenon, where's my money? -Borno
    3. Re:Mainly GC but sometimes... by GileadGreene · · Score: 2, Informative
      Except that
      finalize
      is called by the garbage collector right before collection, not automatically invoked when the object goes out of scope.
    4. Re:Mainly GC but sometimes... by Karma+Farmer · · Score: 1

      But why couldn't they give us a default "going-out-of-scope" method?

      That would be the "IDispoable" interface and the "using" statement in c#.

    5. Re:Mainly GC but sometimes... by pediddle · · Score: 1

      Or "try/finally" in C# or Java.

    6. Re:Mainly GC but sometimes... by ComputerSlicer23 · · Score: 1
      try/finally isn't automatically run when you go out of scope. Yes the finally block is always run when you leave scope, but you must remember to wrap blocks of code with it, and put the proper contents in it. With C++ a destructor is always run when you go out of scope. Always barring an exception happening during an exception handling.

      I wish Java had that, even if I didn't get to clean up memory with it. If only so I could use it to close files that go out of scope. Even if I had to declare the variable special to promise to never ever make a copy of the reference. I'd put up with that to deal with simple things like closing happening automatically without having to remember to add the try/finally block.

      Kirby

    7. Re:Mainly GC but sometimes... by emarkp · · Score: 2, Insightful
      What I don't understand is why they couldn't have written Java (and .NET) so we could have our cake and eat it too.
      They have. Visual Studio 2005 adds syntax to Managed C++ (C++/CLI) to allow you to manage your lifetime and memory separately. Herb Sutter has been talking about this for at least a year IIRC. Dinkumware even made the STL work with it.

      See for instance this article. I'm not currently developing on .Net, but I'm hoping that these extensions can be considered at sometime for standard C++. I'm no MS apologist, but it really does seem to be the best of both worlds.

    8. Re:Mainly GC but sometimes... by cpeterso · · Score: 1


      Though, since GC is not guaranteed, finalize() is not guaranteed to be called either (like a C++ destructor is).

    9. Re:Mainly GC but sometimes... by ultranova · · Score: 1

      Though, since GC is not guaranteed, finalize() is not guaranteed to be called either (like a C++ destructor is).

      In theory it might not be. In reality, considering the rate at which most Java programs I've seen create new objects, it is (except for objects created just before the program exits) ;).

      --

      Forget magic. Any technology distinguishable from divine power is insufficiently advanced.

    10. Re:Mainly GC but sometimes... by flux · · Score: 1

      You still wouldn't want to use a Java finalize to for example release a database lock.

    11. Re:Mainly GC but sometimes... by GileadGreene · · Score: 1

      Which was basically my point.

    12. Re:Mainly GC but sometimes... by plover · · Score: 1
      Thanks for the link, I saw Kate's presentation on C++/CLI at TechEd earlier this year. It sounded really good, but she also pointed out if you do any C++ things your code was no longer "verifiable" (in terms of .NET) It was really cool that she was able to recompile any old C++ program as a .NET assembly (no changes.) But the reason those things work is the code becomes "mixed", with some machine language, some MSIL. The benefits of verifiable .NET assemblies (things like assured correctness of memory management) are not present when the whole assembly isn't pure .NET.

      .NET (as defined by the MSIL) simply does not have support for a "going-out-of-scope" method. Making your application developers call a .cleanup function defeats the purpose of wrapping the resource in the class. And .Finalize is still only called at GC time, not when it goes out of scope. So yes, having access to that functionality through the C++ side is a "good thing." The C++/CLI language is good for developers. It allows us to access .NET functionality from ordinary C++, but it isn't quite the same as a full .NET assembly.

      Take a look at this article on MSDN about the differences betweeen mixed, pure and verifiable ("safe") code.

      --
      John
    13. Re:Mainly GC but sometimes... by Arandir · · Score: 1

      sometimes it would really be nice to have more direct control

      Bingo. This is the major point that all the GC zealots overlook. They might have a point if every piece of software out there was a high level business app running on a system with unlimited resources, but reality is different. I'm a systems software developer writing code for embedded systems, so I need direct control over my memory allocation and deallocation.

      If all you're doing is shunting data and messages back and forth, then GC is nice. But when you start writing low level code the lack of control becomes a major hindrance.

      p.s. I've got this vision of GC as the result of a rotten banana. Some developer left a banana in his cubicle over vacation and it stunk up the whole building. Because he forget to deallocate his banana to the trashcan, the entire development team has been forbidden from eating snacks in their cubicles ever again. Most of us are capable of throwing away our trash and deallocating our memory, but the lazy ass incompentents ruined it for everyone.

      --
      A Government Is a Body of People, Usually Notably Ungoverned
    14. Re:Mainly GC but sometimes... by emarkp · · Score: 1
      I don't think that assessment is correct. For instance this blog (from last week) says precisely the opposite:
      Even from a pure CLR standpoint, C++/CLI has some distinct advantages over other C# and VB.NET, such as deterministic destruction, stack semantics for managed classes, and superior optimizations.
    15. Re:Mainly GC but sometimes... by bckrispi · · Score: 1

      Of course not. But nor would you want to wait until the object is necessarily "out of scope" either. Such resources are best freed manually as soon as they're no longer needed. Which may happen loooong before an object using it goes out of scope.

      --
      Xenon, where's my money? -Borno
  4. Re:Garbage by Anonymous Coward · · Score: 0

    They collect ours every Wednesday, blue boxes every second Wednesday.

  5. Situational by panth0r · · Score: 1

    Personally, I think C++ would be overall best-choice, but it really depends on the situation. If security was in question, I might opt for manual memory managment, but if performance was not a big issue, then certainly garbage collection can be included. As a student, when I programmed, I always used garbage collection, becasue I was lazy and there were no real security issues, even as a researcher, I was more worried about sheer functionality then security, but now in the real-world, where your code is going to be right there with people you don't trust, I am careful with what I do and am paranoid about security, and therefore, won't let a machine take care of it for me. It's all situational...

    --
    I like suggestions, but I don't like contributing towards them.
    1. Re:Situational by Jerf · · Score: 4, Insightful

      If security was in question, I might opt for manual memory managment

      Wha? The evidence is against you. It's not the GC'ed languages that have buffer overflows, and that's the number one security flaw at the moment (though #2, "improperly escaped strings resulting in spilling across a boundary", i.e., XSS, SQL injection, etc. is coming up on it fast as more people use GC'ed languages).

      If security is an issue, you want GC and automatic buffer management like Java, Python, Perl, what have you, not manual management and the resulting opportunities for misallocation like in C and C++.

      (Yeah, yeah, if you program perfect C++ code it's possible to get it right. But I'm not talking theory, I'm talking about what happens in the real world, and in the real world, there seems to be quite a supply of less-than-perfect C/C++ programmers allocating buffers. You have to be on crack to argue otherwise.)

    2. Re:Situational by Anonymous Coward · · Score: 0

      Wha? The evidence is against you. It's not the GC'ed languages that have buffer overflows

      "Wha?" indeed. The reason GC'ed languages typically don't have buffer overflows is that they ALSO tend to do bounds checking.

      A GC'd language without bounds checking would probably be more dangerous, because chances are good that it's compacting holes such that one allocation is just off the end of every other. (ie, a buffer overflow is more likely to write into another buffer)

      The most easily exploited buffer overflows are on the stack anyway, which has completely automatic deallocation in C.

      not manual management and the resulting opportunities for misallocation like in C and C++.

      GC doesn't necessarily affect how you allocate memory either.

      The worst security problem inherent in a program with exploitable memory leaks is a denial of service when you run out of memory. In some languages (anything without exceptions) this can be compounded by a lack of error checking around allocators.

  6. What "performance issues"? by itistoday · · Score: 4, Insightful

    Garbage collection does not equal poor performance. In some instances, it actually speeds things up--when done properly. Take, for example, the D Programming language. It's just as fast as C (faster in some cases) yet it has a garbage collector. The reason is that most programmers tend to not realize that the free() operation actually takes up a decent amount of CPU cycles, and when you're freeing a bunch of little things all over the place, the overhead tends to add up. With a well-designed garbage collector, however, memory is freed all in one big chunk in a single go, and thereby decreasing that overhead. The myth that garbage collection = poor performance is just that, a myth, and most likely started by people who associate Java's performance issues with garbage collection.

    1. Re:What "performance issues"? by keesh · · Score: 1

      Which is only true when you're dealing with badly written manual memory management. C++ custom allocators avoid that problem, and let the programmer specify the best behaviour for every given situation.

    2. Re:What "performance issues"? by be-fan · · Score: 4, Insightful

      In theory C++ custom allocators let the programmer specify the best behavior for any given situation. In practice, very few people use it except for the simple case of pool allocation (which is an optimization you can make in the more sophisticated GC systems). The problem with the C++ mechanism is that it always exposes 100% of the complexity, even in the 99% of the time that you absolutely don't need it.

      --
      A deep unwavering belief is a sure sign you're missing something...
    3. Re:What "performance issues"? by keesh · · Score: 1

      ...and you can ignore it whenever the code profiler shows you that you don't need to care about it, and you can switch allocaters extremely late on in the development process.

    4. Re:What "performance issues"? by treerex · · Score: 2, Insightful

      The reason is that most programmers tend to not realize that the free() operation actually takes up a decent amount of CPU cycles, and when you're freeing a bunch of little things all over the place, the overhead tends to add up.

      This depends entirely on the underlying memory manager. Using pooled allocation or other "zone-based" allocators can obviate the hit of these frees. As with many things, it's a tradeoff between the time spent putting a block back on its free list (naive implementation) to storing appropriate metadata with each allocated block to "deallocate" it in almost constant time. There is nothing magical about GC here.

      With a well-designed garbage collector, however, memory is freed all in one big chunk in a single go, and thereby decreasing that overhead.

      Sure, memory is freed in one chunk, but you forget the time spent finding unreferenced blocks and copying them (I assume, since you imply blocks are coallesced into one big block).

      The myth that garbage collection = poor performance is just that, a myth, and most likely started by people who associate Java's performance issues with garbage collection.

      Because those of us who have used Java since the mid-90s remember when the first JVM's GC sucked like a giant black whole. I remember at OOPSLA '99 Sun had their GC engineers walking around in garbage man's overalls to show that they were serious about improving GC performance in the language.

      GC performance issues have been around a lot longer than Java, by at least three decades.

    5. Re:What "performance issues"? by Spy+Hunter · · Score: 3, Insightful

      You can't ignore the complexity of manual memory management. You must free all your allocations, and you must police dangling pointers. C++ exposes that complexity all of the time, even though you only need it occasionally, if ever. You can use a smart pointer class, but the more sophisticated of those are simply slow unsafe reference-counting garbage collectors...

      --
      main(c,r){for(r=32;r;) printf(++c>31?c=!r--,"\n":c<r?" ":~c&r?" `":" #");}
    6. Re:What "performance issues"? by frantzen · · Score: 1

      GC does not free one big chunk in a single go. They free many small chunks in a single go.
      You're confusing GC with objstacks which can do a single huge free but they're not suitable for many cases and just don't work at all if you're using tons of memory and your address space gets fragmented.
      If you use a slab allocator (read the Bonwick papers) you'll probably see a negligble free() cost and very low allocation costs once you have complex objects.

      My personal biggest gripe with GC is that it blows out the whole dcache in one go.

    7. Re:What "performance issues"? by Anonymous Coward · · Score: 0

      You're arguing that instituting an intermittent inherent lag from the free() operation being executed on several pre-decided chunks of memory at a single point in time is better than the slight slow-down in general gained by running free() as needed dynamically? Dude, you're a fucking moron.

  7. Pros and cons by studerby · · Score: 4, Insightful

    As someone who works on long-lived projects with a mid-sized team (a dozen or so developers), I prefer a GC-based language. The biggest pro is the great reduction in memory leaks, closely followed by the productivity increase by not having to think about allocation/deallocation (very much). The biggest con is that far too many "young whippersnappers" seem to think memory allocation/deallocation is therefore "free" in a GC-based language and will take absolutely no care at all about when they allocate (e.g. will allocate a largish object inside a very tight loop instead of allocating it outside and reusing it...). And the 2nd biggest con is that a lot of developers can't believe you can have memory leaks in a GC-based language, won't look for them until you rub their nose in them, and don't really know how to find them when they look.

    --

    .sig generation error:468(3)

    1. Re:Pros and cons by metamatic · · Score: 4, Insightful
      And the 2nd biggest con is that a lot of developers can't believe you can have memory leaks in a GC-based language, won't look for them until you rub their nose in them, and don't really know how to find them when they look.

      I've always thought that the use of the term "memory leak" to describe resource management problems in Java is a really poor choice, as it's quite a different problem from a memory leak in (say) C.

      Keeping memory allocated and referenced for longer than you need it isn't really a leak, to my mind. It's just bad programming. To me, a memory leak is when you lose the pointers to a piece of allocated memory, so the code is no longer able to deallocate it.

      In other words, your developers might give a better answer if you ask "Are there objects you keep around longer than necessary?", rather than "Are there memory leaks?"

      Or maybe I'm the only one.

      --
      GCHQ Quantum Insert installed. If only our tongues were made of glass, how much more careful we would be when we speak
    2. Re:Pros and cons by interiot · · Score: 1

      On the other hand, it's so cool that "young whippersnappers" can write a perl one-liner that productively creates a several-megabyte hash table these days, as compared to 10 years ago when in the "640kb should be enough for anybody" days, doing anything that took any memory at all was exceedingly painful.

    3. Re:Pros and cons by try_anything · · Score: 0, Flamebait

      Or maybe I'm the only one.

      You're certainly not. I would be pretty pissed off if someone kept telling I had a memory leak in my Java program when he really meant that I was wasting memory by keeping objects "live" longer than necessary. And I suspect the ones who got their noses rubbed in it think he's a jerk for using terminology in an unexpected way and then treating them like they're stupid for not understanding it.

    4. Re:Pros and cons by Spy+Hunter · · Score: 1

      You're not the only one. In a garbage collected language, instead of talking about memory leaks, refer to "memory hogs". It makes more sense.

      --
      main(c,r){for(r=32;r;) printf(++c>31?c=!r--,"\n":c<r?" ":~c&r?" `":" #");}
    5. Re:Pros and cons by Jonboy+X · · Score: 1

      When a Real Java Programmer refers to a Java "memory leak", (s)he's being a little bit snarky. Real Java Programmers know that there's no such thing as a traditional memory leak in a Java program, so they use the term generically to refer to inadvertently unfreed memory.

      Beware, for by openly objecting to this usage, you open yourself to the Real Java Programmer for characterization as an old-school programmer (the bad, bit-flipping kind) or worse, a n00b in need of a lecture. The best approach, rather, is to nod, smile and call them a jerk under your breath.

      Or better yet, bitch about them on Slashdot.

      P.S.: I'm a Java guy myself, but this post is only half-sarcastic. I'll leave figuring out which half as an exercise to the reader.

      --

      "In a 32-bit world, you're a 2-bit user. You've got your own newsgroup, alt.total.loser." -Weird Al
    6. Re:Pros and cons by IamTheRealMike · · Score: 1

      You can still "leak" in Java, for instance by forgetting to null object references that then keep a huge section of the heap graph lying around without realising it. Common ways to do that include not disconnecting event listeners, and having an object provided by a library refer to one of your objects, not realising that the library object is being tracked in some global variable somewhere.

    7. Re:Pros and cons by RAMMS+EIN · · Score: 1

      ``And the 2nd biggest con is that a lot of developers can't believe you can have memory leaks in a GC-based language''

      If you can, your garbage collector is broken. The whole point of garbage collection is that it reclaims the memory used by objects that can no longer be accessed. If your collector is doing it's job, your program can't leak memory.

      --
      Please correct me if I got my facts wrong.
    8. Re:Pros and cons by autOmato · · Score: 1

      If you can, your garbage collector is broken.
      Not neccessarily. With a reference counting GC you can have circular references between objects that can't be reached anymore but wont be collected either. This is a problem of this particular GC algorithm but one wouldn't really call the GC 'broken' because of it.
      It really depends of your definition of 'broken'.

    9. Re:Pros and cons by Keeper · · Score: 3, Insightful

      Unless the language specifies that you can't have circular references between objects, I would consider that broken: the application can get into a state where orphaned objects are not garbage collected.

      Reference counted garbage collection models are inherantly flawed. Leaks are harder to find and easier to provoke. You might as well not have them if you've got to "delete" the references to the other objects.

      Modern garbage collection algorithms do not have this sort of problem.

      What bothers me about garbage collection is that it only solves part of the problem: memory is not the only resource your application holds onto, and the kludges you have to make to deal with them in garbage collected languages are just annoying (hey, you don't have to worry about cleaning up after an allocation ... unless your object has a handle in it; have fun memorizing which objects you have to twiddle with to "release" the resource). If memory didn't have a different release pattern than other resources it wouldn't be a big deal, but ...

    10. Re:Pros and cons by jrstewart · · Score: 1

      The literature tends to define garbage as any object that cannot affect the results of any future computation. Pointer reachability is simply a useful conservative approximation. There are some proposed GC systems (I don't believe any have been implemented in a real system) that attempt to do better and collect some objects that are still reachable.

      So those objects in your program are garbage, and you do have a memory leak.

    11. Re:Pros and cons by studerby · · Score: 1
      That's a great theory... Unfortunately it relies on a very narrow definition of "memory leak". In the real world, running out of memory 'cause you screwed up is a real problem (and the basis for a set of development products) in Java, and it's not the fault of the GC algorithm. You leak memory in a GC-based language by having things that can be accessed, but shouldn't be (and because they shouldn't be, you usually don't know about it until your big development effort starts crashing with out of memory errors).

      Try Googling for:
      "memory leak" java

      Or as an example of the problem and one approach to fixing it see this article on IBM developerWorks.

      --

      .sig generation error:468(3)

    12. Re:Pros and cons by RAMMS+EIN · · Score: 1

      ``What bothers me about garbage collection is that it only solves part of the problem: memory is not the only resource your application holds onto, and the kludges you have to make to deal with them in garbage collected languages are just annoying''

      Could you elaborate on that a bit? I'm too tired right now to think of any cases that cannot be easily dealt with.

      --
      Please correct me if I got my facts wrong.
    13. Re:Pros and cons by RAMMS+EIN · · Score: 1

      We can argue back and forth about the definition of memory leak, but let's not do that. Instead, I'll argue a different point with you, namely that you can't blame the language for retaining objects that you don't need anymore. These are programming errors, and if programmers keep making them, because they are not aware of the fact that they can, they are just incompetent.

      The article you link to provides a nice example of how to write incredibly bad software. Instead of fixing the problem at its root by putting the socket and its associated data in a single object, extra code and data are introduced for maintaining the link between the socket and the global map holding its associated data, furthe boosting code size and memory usage and introducing additional sources of bugs.

      --
      Please correct me if I got my facts wrong.
    14. Re:Pros and cons by Keeper · · Score: 1

      This is an issue for any acquired resource where "lazy" release/freeing is problematic.

      Ex: perhaps only 16 handles to a certain resource are available at any given point in time, or perhaps it is acquiring an exclusive handle to a hardware device, or cases where a limited number of connections can be established with a database server, open files, etc.

      The 'expected' behavior is for those resources to be freed after the object leaves scope, but you and I both know that with most garbage collection algorithms this is not the case.

      These sorts of things are always worked around by implementing some sort of "disposal" pattern on the object, which is a fine way to work around the problem. But at that point you've back to square 1 -- you've got to make sure you call dispose before the object is orphaned.

      As you say, these cases can be dealt with. But as I say, it essentially negates the benefits of garbage collection in the first place.

      It isn't an easy problem to solve mind you, so I can't say I'm surprised it hasn't been. :) I think there was actually some interesting stuff added to .Net 2.0 which allows you to give the runtime "hints" about other types of resources, their limits, and when to start attempting to reclaim some of those resources. A step in the right direction at least. :)

    15. Re:Pros and cons by RAMMS+EIN · · Score: 1

      ``Ex: perhaps only 16 handles to a certain resource are available at any given point in time, or perhaps it is acquiring an exclusive handle to a hardware device, or cases where a limited number of connections can be established with a database server, open files, etc.''

      Yes, of course. But this is not affected by whether you use automatic memory management or not. Unless, of course, you're trying to make the memory management take care of your files or connections for you. In that case, you're trying to manage one resource (files or connections) by managing another resource (memory). It should be obvious that this doesn't work in cases where the availability of these resources isn't coupled.

      I still haven't managed to think of any cases where automatic garbage collection makes managing resources more difficult.

      ``The 'expected' behavior is for those resources to be freed after the object leaves scope, but you and I both know that with most garbage collection algorithms this is not the case.''

      Freeing your resources when something goes out of scope is trivial. It's exactly in cases where scope doesn't correspond to object lifetime (e.g. returning allocated objects from functions) that automatic memory management is most useful (and sometimes even required).

      --
      Please correct me if I got my facts wrong.
    16. Re:Pros and cons by Keeper · · Score: 1

      If you write an object which consumes one of these finite resources (which is 100% of the time in nearly every garbage collected language), that resource isn't "released" until the object is destroyed, which happens at a non-deterministic point in time.

      As I said, the disposal pattern covers this case. I just think it is crappy workaround for the core issue: garbage collection needs to be concerned about more than just managing memory.

    17. Re:Pros and cons by RAMMS+EIN · · Score: 1

      ``As I said, the disposal pattern covers this case. I just think it is crappy workaround for the core issue: garbage collection needs to be concerned about more than just managing memory.''

      So you say, but you can't expect the collector for one resource (memory) to do the right thing for a different resource (say, files) when the availabilities of the resources are disjoint. If you want file handles to be garbage collected automatically, you will need a garbage collector for filehandles, because, as you observed, the collector for memory doesn't run often enough. Such a collector could probably share some code with the collector for memory, but it probably doesn't make sense to do a full GC for every resource each time you need one of them.

      The other question you need to ask yourself is why you need a collector at all. If no language manages file handles automatically, is that because these languages are lacking, or is it because nobody besides you needs them to be managed automatically? Can they even be managed automatically? Why are file handles a scarce resource in the first place?

      My hunch is that if you actually analyze code that claims resources other than memory, it's easy to see where the resource isn't needed anymore. Very often, a resource is only needed in a certain block of code. This is easily handled by a construct like Common Lisp's with-open-file. In other cases, you will have to explicitly write code to release the resource. If you can determine at what point of the program it's safe to release the resource, you can write code to explicitly release it there. If you can't determine this, your only choice is to leave it up to some collector. You can use the memory collector for this, but then you'll have to accept the risk that memory doesn't need to get collected as often as the resource you're asking it to manage. In that case, either you will run out of resource, or you will get degraded performance, because memory is collected more often than necessary.

      --
      Please correct me if I got my facts wrong.
    18. Re:Pros and cons by convolvatron · · Score: 1

      some garbage collection environments let you associate
      a destructor with a given object or type of object. it
      still means that your connection will hang around until
      some point after there are no references, but at that
      point you can arrange to call close()

    19. Re:Pros and cons by Keeper · · Score: 1

      You're still missing my point:

      Why is:

      MyObject foo = new MyObject();
      foo.Dispose();

      Better than

      MyObject foo = new MyOjbect();
      delete foo;

      You aren't saving yourself any effort in this case. You've just changed the syntax.

      Garbage collection of memory is a cool idea. I like it. It saves me time and effort for cases where objects don't reference anything but other objects.

      But it could be better if it understood the relationship between memory and what is being held in that memory.

    20. Re:Pros and cons by Keeper · · Score: 1

      Correct.

      The problem arrises when that close() needs to happen before the garbage collector does its thing. Ie: the server runs out of available connections and connection attempts begin to fail.

    21. Re:Pros and cons by RAMMS+EIN · · Score: 1
      ``You're still missing my point:

      Why is:

      MyObject foo = new MyObject();
      foo.Dispose();

      Better than

      MyObject foo = new MyOjbect();
      delete foo;

      You aren't saving yourself any effort in this case.''

      If that's your point, then I haven't been missing it. It's obvious that you won't save any effort in that case. You would be saving effort if the garbage collector did the necessary cleanup when it collects MyObject. Some garbage collectors can do this (I wrote one a few weeks ago).

      However, originally, you stated that there are some situations in which it's problematic when resources held by some object are only released when the object is collected, but you want the resources to be reusable earlier. You suggested that this is a deficiency of garbage collectors.

      What I have been trying to convince you of is that you should not rely on the collector that deals with one resource to also do collection for another resource. The reason is that these resources will probably have to be collected at different rates, and combining collection for multiple resources will either degrade performance by collecting a resource too often, or lead to avoidable failures by collecting a resource insufficiently often.

      However, and this is a separate issue, I have difficulty imagining situations where releasing resources other than memory is a difficult problem, or requires any work at all. Typically, you know exactly from when to when you need the resource. Often, a construct like with-open-file will acquire and release the resource for you, without you or any automatic collector having to do any extra work.

      Basically, what I was hoping you would provide is an example where you acquire a resource (other than memory) that you have to release, but it's difficult to figure out when it's safe to do so. In the meantime, I've come up with an example (in Scheme):
      (define (create-file-reader filename)
          (let ((file (open-input-file filename)))
              (lambda () (read file))))
      This is a function which, when called with a filename as an argument, will return a function (lambda is for creating anonymous functions) which, when called, returns the next expression from the named file.

      Clearly, the file can't be closed when create-file-reader returns, because the returned function might still use the file. It's safe to close the file once the returned function becomes unreachable, because that function is the only object holding a reference to the file. However, there is nothing in the code that actually closes the file.

      In the above case, a garbage collector for filehandles would be desirable. It's not hard to implement such a collector. One way would be to keep a list of file handles; whenever collection is necessary, perform a reachability analysis (the same analysis used for memory blocks), and reclaim any file handles that were not reached. I think the reason no languages (AFAIK) have this, is that it's rarely needed in practice.
      --
      Please correct me if I got my facts wrong.
    22. Re:Pros and cons by metamatic · · Score: 1

      Well, I'm old school in the sense that I wrote Z80 machine code back in the late 70s by hand-assembling it. But on the other hand, these days I wouldn't touch a programming language that didn't have automatic memory management, unless I had a really, really compelling need to do so. I wonder what that would make me?

      Actually, I'm a strong believer in dynamic typing, so that probably makes me Evil in the eyes of Java zealots.

      --
      GCHQ Quantum Insert installed. If only our tongues were made of glass, how much more careful we would be when we speak
    23. Re:Pros and cons by metamatic · · Score: 1

      By your definition (objects in memory that cannot affect any future computation), you can have garbage in programs that don't even allocate memory, for example if there's dead code or library bloat. Does "Hello World" have a memory leak? It certainly has a lot of garbage when it's linked with libc, and maybe the academic literature would agree that it has a memory leak, but I think you'd confuse a lot of people if you used that definition in the real world.

      I don't think memory hogging = memory leaking, and whether something can affect future computation is not always definable. I mean, what about if Amazon's shopping cart system is keeping my cart contents in memory?

      --
      GCHQ Quantum Insert installed. If only our tongues were made of glass, how much more careful we would be when we speak
    24. Re:Pros and cons by Keeper · · Score: 1

      What I have been trying to convince you of is that you should not rely on the collector that deals with one resource to also do collection for another resource

      You're saying that garbage collection should only deal with memory. I'm saying that garbage collection currently only deals with memory, and that it would be better if it dealt with whatever else can be 'collected' as well.

      You've failed to convince me that garbage collection should be restricted to memory resources only; memory and non-memory resources are intrinsicly linked. I see no reason for garbage collection to be limited to memory management.

      you stated that there are some situations in which it's problematic when resources held by some object are only released when the object is collected, but you want the resources to be reusable earlier. You suggested that this is a deficiency of garbage collectors.

      The fact that garbage collectors today only deal with one type of resource IS a limitation of existing garbage collectors. Does this mean that garbage collection sucks? No. Does this mean that existing garbage collectors could be improved? Yes. Does this result in resource starvation that can be hard to track down? Yes.

      What I have been trying to convince you of is that you should not rely on the collector that deals with one resource to also do collection for another resource. The reason is that these resources will probably have to be collected at different rates, and combining collection for multiple resources will either degrade performance by collecting a resource too often, or lead to avoidable failures by collecting a resource insufficiently often.

      You're telling me why it is hard, and why it hasn't been done yet. I fully acknolwedge that it isn't an easy problem to solve, and that is why it hasn't been done yet.

      I don't accept "because doing what you want is hard" as a valid justification for why I should be happy with something that doesn't do what I want.

      However, and this is a separate issue, I have difficulty imagining situations where releasing resources other than memory is a difficult problem, or requires any work at all.

      I feel like I'm talking to a wall here. It isn't hard to manually release them. I never claimed that it was.

      What is hard is keeping track of them. Why do we like garbage collection in the first place? Because it means we don't have to track allocation/deallocation of objects. Yet, if that object holds onto something that is more limited than memory, we have to make sure that "something" gets released before we run out of them. This greatly reduces the usefulness of existing garbage collectors, because you still have to manually manage that non-memory resource linked to the memory resource.

      In short, like manually managing memory, it is a pain in the ass.

      If I've got a limit to the number of window/file/foo handles (or any other resource that the operating system provides a finite number of) I can use in a program, why should I have to go throught he laborious process of manually releasing each handle when I'm done with it? Why can't the underlying runtime know that there is a limit to the number of handles and start collecting orphaned objects holding those handles when we get close to running out?

      I can't give you a simple example that demonstrates "the problem" because this sort of problem generally surfaces only in larger applications that run for long periods of time. You aren't going to see it in a contrived for-loop.

      I have yet to see an arguement made against this other than "so what, you can do it without garbage collection" and "its hard." I know that. I don't care. Those reasons suck. It would be like me telling you "why bother with garbage collection, you can do that with a call to delete".

      You sort of seem to get this towards the end of the post, but your reaction is more like "meh, I don't see the point". I don't know how to illustrate the point any better than I have.

    25. Re:Pros and cons by metamatic · · Score: 1

      Right, but my point is that's not leaking memory--the memory is still being tracked, and may eventually be freed by the program. It's just being a memory hog. It's a different problem to a real memory leak as found in C/C++/Objective-C, which is when the last pointer to some allocated memory is thrown away without deallocating the memory. That's a real leak, because the program can never free the memory.

      --
      GCHQ Quantum Insert installed. If only our tongues were made of glass, how much more careful we would be when we speak
    26. Re:Pros and cons by bluGill · · Score: 1

      Working through your code to see when a file handle is done with and can be closed is exactly as difficult as working through the code to see where memory is done with and can be freed. In most cases when manually managing memory you can tell exactly when you are done with it. There are a few cases where it is hard. Likewise in most cases you know when you are done with a file handle, but in a few cases it is hard to know exactly when you are done.

      In one piece of code I maintain we pass around the handle to the config file. It can be hard to figure out where we are done with this handle, as so many classes need to initialize themself from the file. (I suspect there is some bad design in there, but it works so it isn't a priority to fix)

      With C++ we use RAII, which ties memory with the handle. We never use the raw handle - except in the class. The class is a wrapper for the file, and thus it doesn't have any read/write methods. It has some getFoo/setFoo methods, that read/write the file. The file format can (and has) changed, but the format is abstracted so we don't have to modify other code. In other words good programming practice means you already have the resource limited to one class that manages it, so why not tie the memory management for that class to the management of the handle that the class manages?

      In short in C++ we tie memory with resources, because it is an easy thing to do. With smart pointers, and stack object allocation, we can be sure that the resource is released when required without thinking. In most cases stack allocation and smart pointers is just as good as GC, but without the overhead. In the few cases where something more complex is required, C++ allows smart programmers to do the more complex operation manually.

    27. Re:Pros and cons by RAMMS+EIN · · Score: 1

      I had enjoyed the discussion so far, but now you're beating dead horses and claiming that I don't get it.

      ``You've failed to convince me that garbage collection should be restricted to memory resources only; memory and non-memory resources are intrinsicly linked. I see no reason for garbage collection to be limited to memory management.''

      Fine, so quit complaining. Just wait for the garbage collector to release your file handles, or do a full GC run when you discover you've been run out of file handles. That way, the GC deals with file handles in addition to memory, just like you say you want. All it takes you is an overridden file open function, and all your filehandles are managed by the GC.

      ``I fully acknolwedge that it isn't an easy problem to solve, and that is why it hasn't been done yet.''

      Not true. It's actually easy. I sketched an algorithm is my previous post, and that algorithm works. It's also very simple.

      I've told you why I think GC of other resources hasn't been done yet, namely that nobody has found a need for implementing it. I think I was wrong; the Perl6 folks actually go through great pains to make their memory collector release memory, and file handles with it, as soon as it can.

      ``What is hard is keeping track of them.''

      I don't agree. Keeping track of any resource (with the exception of remote resources) isn't harder than keeping track of memory, and that's a solved problem. It even seems to me that other resources are usually easier to manage than memory. Before you make the mistake of thinking this means I think garbage collection isn't necessary for them, please recall that I proved that it is in my previous post.

      --
      Please correct me if I got my facts wrong.
    28. Re:Pros and cons by RAMMS+EIN · · Score: 1

      ``In most cases stack allocation and smart pointers is just as good as GC, but without the overhead.''

      Are you sure? Smart pointers use reference counting, right? Reference counting is usually one of the slowest ways to do GC, not to mention that it's a fundamentally flawed algorithm for GC. Also, by making the choice between stack allocation and smart pointers, you are making an optimization by hand that good GC-aware compilers can usually make for you.

      --
      Please correct me if I got my facts wrong.
    29. Re:Pros and cons by cakoose · · Score: 1
      By your definition (objects in memory that cannot affect any future computation), you can have garbage in programs that don't even allocate memory, for example if there's dead code or library bloat. Does "Hello World" have a memory leak?

      GP's definition was obviously referring to heap objects. I think you're equating "garbage" with "memory leak". Just because garbage exists doesn't mean there's a memory leak. A memory leak is garbage that will never bee freed (or maybe just kept around for way too long).

      I don't think memory hogging = memory leaking, and whether something can affect future computation is not always definable.

      Not sure what you mean by "definable" but yes, it is an undecidable problem in general (even ignoring external events such as a customer coming back to look at his Amazon.com shopping cart). It is possible, though, to make conservative guesses. For example:

      1. Dog d = new Dog();
      2. d.bark();
      3. print("hi");
      4. d = null;

      A collector might deallocate the Dog object immediately after line 2 because it inferred (somehow) that the object would never be used in the future. You don't necessarily have to wait until the reference (in variable "d") is set to null.

    30. Re:Pros and cons by Keeper · · Score: 1

      Fine, so quit complaining and I've told you why I think GC of other resources hasn't been done yet, namely that nobody has found a need for implementing it

      Oh brilliant arguement. Don't complain that something sucks, so noboody else will realize that it sucks and sees that maybe there is a need for doing it.

      Other people do have a need for it; C# wouldn't have things like the "HandleCollector" class wouldn't exist if nobody had a need for it.

      I sketched an algorithm is my previous post, and that algorithm works. It's also very simple.

      You then listed a set of reasons about why that alorithm is problematic and probably shouldn't be used.

      I don't agree. Keeping track of any resource (with the exception of remote resources) isn't harder than keeping track of memory, and that's a solved problem.

      Then why do we have garbage collection of memory in the first place? If it's "easy" to do, and by virtue of being easy 'improvements' are not worthwhile, then why is garbage collection of memory worthwhile?

      You keep suggesting other ways of doing what I want. I've been there, done that, and don't like it. You keep suggesting workarounds that involve just endless amounts of pointless redundant code.

      Your latest suggestion (force a garbage collection) requires the following for every operation which could potentially consume a handle (which includes any creation of an object I don't "own"/control the code to):

      TheirObject foo = null;
      try {
          foo = new TheirObject();
      }
      finally
      {
          if (foo == null)
          { // todo: code to force garbage collection // todo: code to wait for garbage collection to finish
              foo = new TheirObject();
          }
      }

      That has to be done every time I allocate an object, because I don't know what resources that object consumes in the ctor. I have to do it every time I make a function call, because I don't know what resources that function consumes. And so on.

      That sucks.

      I have never once said that doing what I want can't be accomplished with traditional means. I have consistently been saying that traditional means are a giant pain in the ass, and that when you're using those traditional means many of the benefits of using garbage collection are negated.

    31. Re:Pros and cons by RAMMS+EIN · · Score: 1
      ``Oh brilliant arguement. Don't complain that something sucks, so noboody else will realize that it sucks and sees that maybe there is a need for doing it.''

      It sucks if you insist on having the memory collector also be responsible for collecting other resources. If you insist on having it that way, don't complain that it sucks. I've shown you an alternative that doesn't suck, but you're not convinced you need it. So I'll try explaining one more time.

      Garbage collection takes time. Because most algorithms trace live objects, not garbage, and the number of live objects doesn't tend to change a lot, most algorithms will take less time (in total) if you run them less often. So garbage collection is cheaper when you do it less often.

      If you have the memory collector deal with other resources (let's take the example of file handles again), you have two choices. Either, the collector only runs when memory runs out, or also when file handles run out. In the former case, you may end up not being able to open files, even though you're not actually using as many file handles as you're allowed to use. In the latter case, performance suffers, because you collect both resources when either one runs out.

      I hope you understand now.

      ``I sketched an algorithm is my previous post, and that algorithm works. It's also very simple.

      You then listed a set of reasons about why that alorithm is problematic and probably shouldn't be used.''

      Where is this set of reasons you speak of?

      ``Keeping track of any resource (with the exception of remote resources) isn't harder than keeping track of memory, and that's a solved problem.

      Then why do we have garbage collection of memory in the first place?''

      I think you mistook my meaning. The garbage collector also keeps track of memory. Keeping track of memory isn't hard, therefore writing garbage collectors is easy. The same goes for other resources, which aren't harder to keep track of than memory, as far as I can see.

      ``Your latest suggestion (force a garbage collection) requires the following for every operation which could potentially consume a handle ...''

      It's actually much simpler than you make it seem, at least when you have a sane library that doesn't do a lot of resource allocation without freeing behind your back. For example, to deal with filehandles in C you can define a function gc_open:

      int gc_open(const char *name, int flags, mode_t mode) {
      int fd = open(name, flags, mode);
      /* Collect and try again if
      * the call failed due to lack of
      * file handles.
      */
      if(fd < 0 && (errno == EMFILE || errno == ENFILE)) {
      gc();
      fd = open(name, flags, mode);
      }
      return fd;
      }

      then, instead of using open directly, you use gc_open, and it will automatically run the garbage collector if filehandles have run out. Of course, this is a stopgap measure; you're working around the fact that your language doesn't collect file handles. However, as long as you don't have too many kinds of resources to manage, this isn't too much work.

      Stick it in a library, and you've just added file handle collection to your language! Some languages are even flexible enough that you can substitute your new and improved open for the old one so that the rest of the system will use it, too. That's probably difficult in C or Java.

      Anyway, I hope I've illustrated that it isn't as bad as you seemed to think it was. You certainly don't have to gc-and-retry for _every_ function call you make; only at the place where you actually allocate resources.

      ``I have never once said that doing what I want can't be accomplished with traditional means. I have consistently been saying that traditional means are a giant pain in the ass, and

      --
      Please correct me if I got my facts wrong.
    32. Re:Pros and cons by Anonymous Coward · · Score: 0

      Have you ever used Common Lisp? It has macros for pretty much every severely limited resource that ensures proper deallocation. An example is with-open-file. You pass it a file name, options (like read only, or the write mode, just like you would to fopen), and a chunk of code. It runs the code then closes the file. The way that it is implemented guaruntees that the file will be closed when execution leaves its scope, even if it left scope in some strange way (such as an exception or a throw). There's macros like this for all sorts of things, and the language even gives you an easy way to implement your own called unwind-protect. It lets you have really fine-grained control over resource allocation while at the same time preventing a lot of the headaches of having to remember to send deallocation messages to objects like you have to do in most gc languages.

  8. I am strongly in favor of it by Anonymous Coward · · Score: 1, Funny

    After a few days, the garbage really starts to stinks and all sorts of animals come around.

    1. Re:I am strongly in favor of it by Anonymous Coward · · Score: 0
      Q: How do you know if a hippy gnu programmer lives in your neighborhood?

      A: Your garbage cans are knocked over and your dog is knocked up!

      Q: How do you know if a hippy gnu programmer has been at your house?

      A: He's still there!

      Q: Why do hippy gnu programmers smell so bad?

      A: So blind people can hate them too!

  9. Garbage Collection vs. Manual Memory Management by Dual_View · · Score: 2, Interesting
    Manual memory management is similar to assembly language in a certain way: everybody should know how to use it, but they should strongly avoid actually having to use it in most cases. Even though I like to write code in C, I still understand the value of garbage collection. This goes back to the old adage: "Programmer time is more valuable than processor time." On the other hand, there are still a few instances where the manual method is the best tool for the job.

    But then, the question is rather ambiguous. Is the writer asking:

    • "How much does garbage collection affect what language you choose to code in?"
    • "If you were designing a programming language, would you implement garbate collection? If so, what kind? If not, what memory allocation strategies do you use?"
    • "In what situations would you find garbage collection to be the most useful? When is manual memory management better?"

    I'll leave further interpretation of the writer's words to other posters, as well as more thorough responses.
  10. It all depends by unr_stuart · · Score: 3, Interesting

    I've always had the philosophy, "use what makes the job easiest." Typically, this involves garbage-collection. However, one of the biggest problems I have with garbage collection is that you can't have your cake and eat it too. Meaning, you can get all the memory you want, but you can only access it at a high level (think Objects in Java). In C/C++ however, you can call malloc/new, create a big pool of memory (or just a single object), and then do whatever the heck you want with it. But again, as the subject says, it all depends on which method helps get the job done, and so far neither has been perfect for everything.

    1. Re:It all depends by BigZaphod · · Score: 1

      Meaning, you can get all the memory you want, but you can only access it at a high level (think Objects in Java). In C/C++ however, you can call malloc/new, create a big pool of memory (or just a single object), and then do whatever the heck you want with it.

      Couldn't you do the same in Java by allocating a huge array once and then just doing things within that array? I admit it might not be quite as convenient, but if you really needed to do it, I think it could be done. (Note: Not a Java Programmer)

    2. Re:It all depends by unr_stuart · · Score: 1
      Yes, you could just allocate a huge array, but that has some problems:

      1) Possibly slow/complex initalization
      2) Difficult to take advantage of OO
      3) Unlike in C++, the bytes in the array couldn't be easily made into a reference to a Java object (you'd have to use JNI)

      The first isn't as difficult/complex in a programmer managed memory space (as in C++ with the placement new operator). The second is the entire reason why you would use Java in the first place. So yes, it could be done almost the same way, but it would have some major drawbacks.

  11. If C++ Memory Management by sgent · · Score: 1

    If the C++ memory management approach work, we wouldn't have spent the last two decades being terrified of buffer overruns. Just like any complex problem, the more details a programmer has to track, the more likely an error will exist. Its the reason we adopted subroutines, modules, and eventually objects. Memory management is almost never core to a project -- and the best way to manage it can vary due to OS, CPU, or underlying language. Focus on the core competencies, and don't reinvent the wheel.

    1. Re:If C++ Memory Management by plover · · Score: 1, Insightful

      Buffer overruns are not always the fault of poor memory allocation. Yes, they can be caused by allocating too little memory (or writing too much data), but they can also be caused by doing pointer math incorrectly, incorrect static casting, or one of a dozen other reasons. A garbage collector doing its job is not even related to the problem.

      --
      John
    2. Re:If C++ Memory Management by try_anything · · Score: 2, Interesting

      I agree with a comment posted elsewhere that unchecked memory access and manual memory management, while both unsafe and fertile sources of errors, are different beasts.

      Manual memory management is a control issue. Unchecked memory access is a matter of asceticism.

      Buffer overruns happen because the devotion to performance and minimalism among a certain crowd is religious. Because of this, the C++ standards guys were terrified of encouraging the use of anything slower and safer than what a C programmer would do. In std::vector and boost::array the default (and readable) access operator [] is unchecked, and checked access is relegated to the ugly at() method. This is a political decision that turns on its head the principle that quiet syntax should be used for routine, safe operations and ugly syntax should be used for rare, dangerous operations.

      Using template metaprogramming, it's easy to produce your own array classes with bounds-checking chosen at compile time, but because the survival of C++ depended on the "just as fast as C!" slogan, unchecked access was officially encouraged and has unsurprisingly become the norm among C++ developers.

      Rationally, even a developer who expects that bounds checking will always be too expensive in production should insist that bounds checking be easily enabled at compile time. Electric Fence helps with that, but template metaprogramming is a more straightforward solution.

    3. Re:If C++ Memory Management by Anonymous Coward · · Score: 0

      "we wouldn't have spent the last two decades being terrified of buffer overruns"

      If you're "terrified" of buffer overruns, then you probably don't have the personal constitution to be a 7334 h4x0r. Most 7334 hax0rs are, at worst, "concerned" about buffer overflows, and, at best, "don't give two exrements" about buffer overflows because the user can just exit and restart the app and if the user wants the app fixed well the source code is available so go and fix it yourself you n00b 100sar user.

  12. GC v. Direct allocation by Fubar420 · · Score: 2, Insightful

    As a programmer-come-sysadmin, I vote both. Which has its issues all its own...

    When I programmed professionally, I craved the control of memory management. Objects did _exactly_ what was _explicitly_ told to do.

    Now I'm a ruby junkie, and love the OO, GC, Etc.

    Still, yes, for performance reasons, there are good reasons to do it yourself.

    For programming reasons, there are reasons to go GC.

    all in all, GC tends to be great. wouldnt work without it. But there are times I'm mystified as to why an object left scope, got destroyed, etc.

    So I would (as a programmer), like a compromise [and yes, ruby/rails provides this in its own way, but...] All my objects should be GC'd by default. But I want the ability to hook the destructor, and only have it react the way I expect.

    If I want a big block of memory to manage myself, I find an appropriate object for the language (char *, ruby C bindings to a mempool object, unsafe C# (or even safe C#, if you're good), or whatever idiom matches your lang)

    Then again, you dont get pointers in ruby, so I s'pose I'm just whining...

    So from my perspective:
        - Scripters want GC
        - RAM Intensive code needs at least somewhat programmer-managed MManagement
        - Embedded devices need hard kernel memory management
        - Short run applications generally want GC
        - Long running, RAM intensive, frequent paging, or frequently shifted data process generally should go with kernel malloc.

    Cheers.

    --
    -- (appended to the end of comments you post, 120 chars)
    1. Re:GC v. Direct allocation by ultranova · · Score: 1

      Short run applications generally want GC

      Short run applications don't neccessarily need any memory management - since the application is going to exit shortly, you can just leak the memory and let the kernel reclaim it on exit. Might actually be faster that way than wasting time freeing memory that's going to be reclaimed soon anyway.

      After all, if the application is short-run enough, the GC doesn't neccessarily have time to run even once.

      Long running, RAM intensive, frequent paging, or frequently shifted data process generally should go with kernel malloc.

      There is no kernel malloc - it is a C library construct. Besides, aren't RAM intensive long-running processes those that will likely end up with a fragmented heap (due to continued allocations and deallocations), making malloc/free quite slow ? Also, any memory leak in a long-running program is likely to have time to grow severe, so garbage collection might be the way to go.

      --

      Forget magic. Any technology distinguishable from divine power is insufficiently advanced.

  13. Check this out. by dslauson · · Score: 2, Informative
    There was a pretty good discussion and article on slashdot not too awful long ago about dispelling common myths regarding garbage collection and performance in Java.

    It's definitely worth checking out before people go spouting off the traditional rants against garbage collection.

    Of course, determining which one is best always depends on your application and your available resources, among other things. There are good arguements for both in various situations. I code C++ for embedded devices for a living, which means that I am working with the new/delete/malloc/free model, but for school projects I really like to work with Java, because it lets me focus entirely on implementing an algorithm without having to spend any time thinking about memory allocation or the underlying hardware.

  14. Both by DigitalKhaos23 · · Score: 1

    I actually use both gc'd and native code in my apps. Generally speaking, when some component is time critical i tend to use native code, and when it's not the benifits outweigh the cons to not use a a gc'd environment

  15. Getting it backwards by MarkusQ · · Score: 1

    aside from the performance issues, predictable memory management can be used for controlling access to files and similar resources, creating safer thread locking code and even providing better error messages.

    This is silly. None of these have any connection to garbage collection; you can write "destructor's" in a garbage collected language, and do everything in them just as you would have in a non-GC language.

    The advantage comes from the RAII style of coding, not from the absence of a garbage collector. In fact, most modern GC languages provide better RAII support, in that there is no way to get an uninitialized object object.

    In a way, it reminds my of the old bounds-checking arguments. A fair number of people used to resent/resist built in bounds checking, with very similar arguments (performance, trusting the coder, illogical correlations between manual bounds checking and various Good Things(TM), etc.) and thus we still to this day struggle with buffer overruns and related problems.

    --MarkusQ

    1. Re:Getting it backwards by Anonymous Coward · · Score: 1, Insightful

      Huh? You can't do RAII in GC languages because you've no control over when the destructor is called. See the Wikipedia article in the original question.

      Guaranteed cleanup isn't sufficient for RAII. It's no good knowing that the mutex you've allocated will be cleaned up at some point in the future.

    2. Re:Getting it backwards by Profound · · Score: 2, Interesting

      >> you can write "destructor's" in a garbage collected language

      You mean like Java's Object.finalize()?

      The same one that causes significant performance problems fundamental to how GCs work, and is not guaranteed to execute in any specific order, or even at all?

    3. Re:Getting it backwards by MarkusQ · · Score: 1

      You can't do RAII in GC languages because you've no control over when the destructor is called.

      That's nuts. Just call it yourself, exactly as you would in a non-GC language.

      --MarkusQ

    4. Re:Getting it backwards by MarkusQ · · Score: 1

      There's nothing to stop you from writing your own, and calling it yourself just as you would in a manual-allocation system.

      Think about it--someone could write a C library to use an underlying garbage collection system and on semantic grounds you'd have no way of knowing it, would you? You'd release your memory, the library would mark it as "dead" but otherwise do nothing, and the GC would get around to recycling it when it felt like it. For that matter, the GC might even be in the OS, hidden from the language itself. How would you ever know?

      With that in mind, why does the fact that you know about it change things?

      --MarkusQ

      P.S. You aren't guaranteed that a destructor will be called in a manually managed system, either. If it was guaranteed, the system wouldn't really be manually managed, would it? And nothing in a GC language prevents you from doing exactly the same things you otherwise would have been forced to do.

    5. Re:Getting it backwards by Anonymous Coward · · Score: 0

      You don't call destructors explicitly with RAII. Some languages with GC utilize a combination of a disposable resource interface and a means of specifying an lexical execution environment to contain operations performed on a disposable resource. In Common Lisp for example you might make use of a with-open-file or other with- macro to enclose operations on a limited resource and when out of scope, call the disposal function on the object in question. In C# there's a similar "using" statement for objects that implement IDisposable.

      There is no fully-automatic way of performing desctruction in a GC environment, and you'd have to explicitly call the destructor. In C++ this is done for you when control exits the enclosing scope of a variable.

    6. Re:Getting it backwards by MarkusQ · · Score: 1

      In C++ this is done for you when control exits the enclosing scope of a variable.

      Only for local, stack allocated objects. You still have to call the destructor's manually for heap allocated or global objects. Which doesn't mean you can't do RAII in C++, it just means you have to understand semantics of the language you are using. But then, this is true for any style of programming, in any language. Admittedly, it is much easier to implement most styles in a language such as lisp or smalltalk (which provide rich introspection and little heavy handed bias) than in a language such as java or C (with weak introspection and strong built-in style assumptions)--but "less easy" is not equivalent to "impossible".

      You can use RAII in any real language. You can write structured, functional, or object oriented programs in any real language as well. Conversely, you can write unstructured, spaghetti muddled dreck in any language. The semantics of the language don't matter nearly as much as how well you use them and how rigorously you apply your chosen style.

      --MarkusQ

    7. Re:Getting it backwards by Profound · · Score: 1

      C doesn't have destructors, I was talking about the order of destructor calls.

      In C++ it is guaranteed that the destructors in the following scope will be called "here" in the following order: ~Bar. ~Foo
      {
              Foo foo;
              Bar bar;
      } // here

      Order is also guaranteed when objects are inside other objects. If you think about it, destructors are really just a way of saying "run this code just before this object is deleted". Since (efficient) GCs are non-deterministic and lock-the-world, if you wanted to run the code when an object is deleted, you'd have to be non-deterministic (ie you couldn't batch up deletions which is one of GCs performance advantages) and be forced to unlock the world, run the code, switch back to GC for every object with a destructor. This would not be very fast at all.

    8. Re:Getting it backwards by cakoose · · Score: 1

      C#'s "using (...) { ... }" clause provides the same functionality. Garbage collection doesn't get in the way.

      C++ RAII-style code is implemented using C++'s object destruction rules. Obviously, the same implementation wont work for a language with different object destruction rules. However, the same feature can be implemented differently (as it has been in C#).

      Since (efficient) GCs are non-deterministic and lock-the-world, if you wanted to run the code when an object is deleted, you'd have to be non-deterministic (ie you couldn't batch up deletions which is one of GCs performance advantages)

      GCs batch up the freeing of memory. It could run destructor code deterministically and still wait until later to free the memory. The problem is figuring out when to run destructor code.

  16. C++ and others.... by try_anything · · Score: 5, Interesting

    C++'s constructor/destructor paradigm with predictable object destruction has the benefit of enabling the RAII (Resource Acquisition Is Initialization) idiom. RAII and exceptions greatly simplify resource management in the presence of error handling. Still, even as someone who knows C++ better than I know any other language, I have to admit that for many applications a garbage collected language puts the least mental burden on programmers and produces the fewest memory errors. The burden of arranging all the extra try/catch blocks in Java (because it lacks RAII) has to be weighed against the burden of investigating and fixing memory management errors in C++, and for people using new/delete, Java wins, IMHO.

    C++ programmers should be making very little use of new and delete, though; they should be using smart pointers. I think the article poster misunderstands smart pointers. boost::shared_ptr is a reference counted pointer, but std::auto_ptr and boost::scoped_ptr have nothing to do with garbage collection - they certainly aren't "faked garbage collection" and they certainly aren't unpredictable. They use C++'s object scoping and copying mechanisms to manage memory in a way completely unlike garbage collection. scoped_ptr is the simplest and most predictable memory management tool of all. Taking programmer error into account, it's more predictable than using delete. Even shared_ptr is predictable; when the reference count falls to zero, the object is immediately destroyed, not just marked for destruction.

    Sadly, although C++ is a very powerful language and can be used to write code with few errors, the language as used by beginners is as dangerous as C, perhaps even more dangerous. It takes programmers years to become proficient in all the methods and idioms that make C++ a usable language.

    (I would love to see a language that allows programmers to choose scoped allocation, smart pointer heap allocation, or garbage-collected heap allocation, and uses types to avoid dangerous combinations such as garbage-collected objects pointing to scoped objects or an object pointing to an object in an unrelated scope. Every object would have two types - the object type (int, file, circle, etc.) and the memory management type (scoped with scope S1, scoped with scope S2, garbage-collected, etc.))

    1. Re:C++ and others.... by Anonymous Coward · · Score: 0

      C++.NET?

    2. Re:C++ and others.... by cryptoluddite · · Score: 2, Interesting

      Why do C++ people use the acronym RAII "resource acquisition is initialiation" to talk about when the object is uninitialized? The acronym is just completely wrong, because languages like Java are far more "RAII" than C++ (in C++ you can actually allocate resources without initializing them). It really should be something more like RAIS, "resource acquisition is scope", or LSILS "lexical scope is logical scope", or ODOL "object destroyed on leaving", or RROL "resource released on leaving", or something that actually makes sense. To me it just sounds like more arbitrary complexity and nonsense, so basically like everything else C++.

    3. Re:C++ and others.... by MobyDisk · · Score: 1

      I've never understood why none of the GC languages (none that I know of: Java and .NET) allow this pattern to work. It is EXTREMELY useful! Just because the runtime uses GC doesn't mean you couldn't mark an object for immediate disposal when it leaves scope. Both Java and C# have a mechanism for doing this, but it requires explicitly freeing the object (which defeats the purpose of the pattern).

    4. Re:C++ and others.... by try_anything · · Score: 1

      I think the problem is that live objects managed by the garbage collector may hold references to an object that is scheduled for immediate destruction. Then the language has to choose between aborting, leaving the object alive, or leaving the referring objects in an invalid state.

      I just proposed a solution to this problem, in which safety is enforced by a scope-aware type system, in another comment:

      http://slashdot.org/comments.pl?sid=169616&cid=141 37054

      I don't know if any language already supports this or not.

    5. Re:C++ and others.... by dkf · · Score: 1
      Scoped objects? They never really seemed all that useful to me, but maybe it's a peculiarity of the code I usually write that most significant resources allocated do not have lifetimes linkable to any scope. But that's probably a peculiarity of the code I'm usually working with.

      On the other hand, GC doesn't work too well with it either (because GC across a distributed object system sucks unless your network is perfect). Time-linked lifetimes (which you can update, of course) seem to work better.

      --
      "Little does he know, but there is no 'I' in 'Idiot'!"
  17. usually, I prefer GC by Anonymous Coward · · Score: 2, Informative

    Most new programming languages are using garbage collection

    You mean like Lisp and Smalltalk? ;-)

    The advantages are obvious: programmers no longer have to worry about forgetting to delete allocated memory, leading to far fewer memory leaks.

    In other words: the computer is perfectly capable of figuring out what to do, so let it! This is almost always the best thing.

    When using a manual memory management language, when do you consider the performance and syntactic overhead of faked garbage collection to be worthwhile?

    I haven't used manual memory management in years, except for a couple old C programs that I still maintain (and those are written to be as easy to "visually inspect" as possible.. allocate, use, de-allocate in three separate lines).

    There's rarely good reason to be tinkering around with pointers and other "implementation details". I prefer using very high-level languages (like Haskell for instance) that allow me to express problems and solutions as directly as possible, rather than having to deal with implementation details that only resemble the problem domain from a distance.

    I suppose there are times when you need to override the memory management, so there should definitely be "hooks and hints" where appropriate. And even the highest-level language shouldn't free you from the burden of understanding how computers work. However, I personally haven't needed to know about low-level details in *long* time, not since the Pentium era began at least..

  18. GC by Dr.+Photo · · Score: 5, Informative

    Pros and cons of garbage collection?

    If you don't CONS, you never need to collect garbage. *rimshot*

    More seriously, GC isn't so much about pros and cons, as it is about tradeoffs between the various GC algorithms: time vs. space, low-latency vs. high-throughput, parallelism, etc.

    If you're designing a new language, it should include garbage collection, or nobody will use it (i.e., your target audience can already program in C). You may wish to have multiple GC implementations available for different purposes, perhaps to be selected at compile-time.

    For a good overview of what's available, see http://www.memorymanagement.org/

    My personal favorite is the good old Cheney semi-space collector (and Ephemeral/Generational Garbage Collectors, which are more advanced versions designed to generally have low latency), as it is very straightforward (both to understand and to implement), compacting (it defragments memory, and can perhaps improve cache locality by grouping related objects), and it has high throughput (work is proportional to the amount of live data, not total data).

    If memory usage is of more concern than fragmentation and throughput, a mark-sweep collector may be more your style.

    There are also "real-time" (and "soft-real-time", i.e. bounded latency [see Henry Baker's Treadmill]) collectors, parallel collectors [including an interesting case for reference counting, usually considered a dog performance-wise, as a viable parallel/remote GC method], "conservative" collectors for C/C++ (see Hans-J Boehm's libgc), collectors for real and hypothetical computers with special hardware and/or OS support for GC features, and some collectors that are just plain weird.

    Note also that garbage collection algorithms are considered hard to measure for performance, especially with regard to wall-time latency, so just because a paper(*) claims that a certain GC has certain performance characteristics, be sure to benchmark if it really matters.

    (*) Did I mention papers? If you're serious about implementing GC, getting comfortable reading CS research papers is a must. The book "Garbage Collection" is your best friend here, as it provides a very good overview/survey of said papers and algorithms, and it discusses a lot of pros and cons between various algorithms, and useful variants or adaptations that have been applied to previously-published work.

    Also check out Henry Baker's papers, because he is a memory management demigod: http://home.pipeline.com/~hbaker1/home.html.

  19. Don't know what to say here... by hackwrench · · Score: 1

    The article throws out a bunch of links covering concepts that the writer believes supports the writer's statements. The "controlling access to files and similar resources" links to "Resource Acqisition Is Initialization" which superficially appears similar to BASIC's initializing variables on each entry into scope, and BASIC's a GC language. (I have QuickBASIC in mind, to be more specific). I was confused when writing a TurboPascal program to find garbage in variables until someone explained that TurboPascal doesn't init it's variables. I don't know if TurboPascal is GC or not, but I don't remember explicitly allocating and freeing variables, so I guess so.


    Under "safer thread-locking code" we find another RAII article. Again with the next. I wrote the first part of this post, thinking that each link would cover topics that explicitly described the situation involved.

    To the best of my knowlege, there is nothing intrinsic to either allocation method that would make those tasks easier or harder in either of them.

    I call "Shenanigans!"

    1. Re:Don't know what to say here... by try_anything · · Score: 1

      RAII originated (as far as I know; someone may be able to correct me) as an idiom for using C++ language mechanisms to manage resources. Without knowing those mechanisms, it's hard to see how RAII helps. Here's an example, though:

      int foo()
      {
      ScopedLock lock(getBarMutex());
      if(twiddleBar()) return 1;
      if(diddleBar()) return 2;
      if(fiddleBar()) return 3;
      return 4;
      }

      Here, the method could exit at four different return points, not to mention the possibility of an exception being thrown. Without RAII, you would need a complex control structure to guarantee that the mutex lock was released. Using RAII, you simply put the mutex acquisition in ScopedLock's constructor and the mutex release in ScopedLock's destructor. Because the language guarantees that the lock's destructor will run when you leave the scope, you don't have to worry that some set of conditions will cause the thread to leave this function without releasing the mutex. Without that guarantee, the function would need to be more complex. It would have more lines and a more complex control structure. And no amount of code gives you the confidence that language enforcement does.

      I hope that intrigues you enough to check it out! Be warned, though, RAII requires certain language features, so you may not be able to use it in your language of choice.

    2. Re:Don't know what to say here... by Anonymous Coward · · Score: 0

      And how would that be different to doing the following in Lisp/Scheme:

      (define (foo)
              (with-mutex-lock ((get-bar-mutex))
                      (cond ((twiddle-bar) 1)
                                  ((diddle-bar) 2)
                                  ((fiddle-bar) 3)
                                  (else 4))))

      As other posters have mentioned, GC (which should really be refered to as "Automatic Memory Management") has nothing to do with managing resources other than memory. If RAII is hard/impossible to do in Java/C#, more to do with the language, and nothing to do with GC.

  20. Memory Access vs. Memory Allocation Re:Situational by hackwrench · · Score: 2, Informative

    People seem to have confused Memory Access with Memory Allocation. Neither GC nor PC (programmer collected) should allow memory accesses on out-of-scope data. GC just delays when that out-of-scope data gets freed for reallocation. Those unfamiliar with GC and used to the unreallocated = still-accessible-data situation of improper PC coding think that in the GC world unreallocated means still-accessible, which is not necessarily nor usually the case.

  21. Cocoa and Objective-C by mccoma · · Score: 2, Interesting

    Apple / NeXT takes a reference counting approach. It is not automatic, but it works well once you understand the rules.

    1. Re:Cocoa and Objective-C by feijai · · Score: 2, Insightful

      As an old Obj-C coder, let me respectfully disagree with this. Reference counting does not handle cycles: that's a huge flaw. It forces Apple to promote a notion of "ownership" of object graphs which only works on a small scale. It does not work well: it merely reduces what you need to keep track of (but doesn't eliminate it) in return for a considerable amount of manual labor.

  22. RAII is a bad reason for manual memory management by GileadGreene · · Score: 3, Insightful

    All of the reasons given for manual memory management seem to boil down to a desire to have support for the Resource Acquisition Is Initialization (RAII) idiom, which is hard to pull off in GC languages. But, the alternative idiom Resource Acquisition Is Invocation provides the desired capability in GC languages. Same capability, no chance of memory leaks. So tell me again why manual memory management might be a good idea?

  23. RAII-like techniques, GC, and closures by Temporal · · Score: 1
    RAII techniques like mutex locks and the error message stuff can be implemented without deterministic collection using something like:
    void AcquireAndRun(Resource r, Function f) {
      r.Acquire();
      try {f()} finally {r.Release();}
    }
     
    void doSomething(Resource r) {
      AcquireAndRun(r, lambda () {
    // Here, r has been acquired.
        read(r);
        write(r);
      });
    // Once we get here, r has been released.
    }
    (Note: Those comments were indented properly, but Slashdot messed them up.)

    Of course, this will be hard to use unless your language supports closures. Sadly, most imperative languages (e.g. Java) do not. But, hey, I'm a functional language person so I'm not going to try to defend them.

    Some programming languages, which usually predictable memory management, can also be made to behave like they are garbage collected - for example, Boost provides various C++ smart pointer classes.

    Aside from the obvious problem with cycles, note that reference counting is slow. Very, very slow. Since you need to use an atomic counter, every copy of a refcounted pointer requires inter-processor communication (on a multiprocessor system). Do not underestimate how slow this is. Yes, it is much slower than real GC.
    1. Re:RAII-like techniques, GC, and closures by cryptoluddite · · Score: 1

      Of course, this will be hard to use unless your language supports closures. Sadly, most imperative languages (e.g. Java) do not. But, hey, I'm a functional language person so I'm not going to try to defend them.

      Java supports closures just fine, as objects. A java anonymous class is a closure. If that really offends you, try calling them multi-closures, since they combine multiple functions with a lexical scope instead of being limited to just one function.

      In some languages you have a closure of just one function, but that goes against the "strict constructionists" as in Eiffel since you have objects with no state (Meyer would throw down, as if anybody would care). Or you have the problem of being only weakly object oriented, since every closure is the same type (for example you can't get a closure object and perform a meaningful instanceof operation). For these reasons, Java's anonymous inner classes make the most sense for a closure in an OO language... if only the syntax was a bit less.

    2. Re:RAII-like techniques, GC, and closures by Temporal · · Score: 1

      Yes, anonymous inner classes work... but the are awfully cumbersome to use.

      they combine multiple functions with a lexical scope instead of being limited to just one function.

      I prefer to add such complication only when it is actually needed. In a typical functional language you can always group a bunch of closures into an aggregate if that's what you want.

    3. Re:RAII-like techniques, GC, and closures by Anonymous Coward · · Score: 0
      No.

      Contrary to your assertion, closures have state. The difference between a function and a closure is that the latter closes over variables in the surrounding lexical scope. It's what lets me do this:
      (defparameter *closure*
        (let ((i 0))
          #'(lambda () (incf i) i)))
       
      (funcall *closure*)
      = 1
       
      (funcall *closure*)
      = 2
      (that 'i' is not a global variable, btw; it's part of the closure that just happens to be bound to the global variable '*closure*')

      Of course closures and functions have types. They are all instances of subtypes of 'function' (or 'funcallable', or whatever tags objects that puport to conform to your function calling protocol).

      Java-style objects can be used to simulate something similar to closures. But they're not. Firstly, they don't close over the local lexical state. So if you wish to use local variables, you will need to copy them into and out of your "closure object". Secondly, they lack a common calling protocol. Java does not (AIUI) have a standard for which method to invoke when passed an object into a functional context. Without this there is no way to build a common library of functional operators, like map or every.

    4. Re:RAII-like techniques, GC, and closures by Anonymous Coward · · Score: 0

      I prefer to add such complication only when it is actually needed. In a typical functional language you can always group a bunch of closures into an aggregate if that's what you want.

      And another name for that aggregate is an Object. Java is an object-oriented language; it should have closures that are objects. Functional languages should have closures that are functions. That's just being sensical.

      That's why C# delegates cause such a mess... hundreds of methods in, some related and some not and lacking consistent naming, versus a few Java's event listeners that group the events together into logical units (mouse events, keyboard events, etc). Delegates (like 1-function-only closures) are not an OO concept, but they are relied on heavily in the .Net apis.

  24. GC memory leak... by hackwrench · · Score: 1

    No, you can have a memory leak of the PC (programmer collection) type in a GC system. You clearly haven't had an experience similar to the QuickBASIC "String space corrupted" error. QuickBASIC is a GC system.

  25. Explicit management has its own costs by Pseudonym · · Score: 4, Insightful

    The answer, as always, is "it depends". I'm firmly inside the "right tool for the job" camp.

    Manual memory management is not free. In some circumstances, it can be quite expensive. There is a group of programmers who are best described as "rabidly anti-GC". These people are almost all completely unaware of the costs that manual memory management can impose on your code.

    A multi-threaded program, for example, can allocate memory from any arena, but it MUST return a block to the arena from whence it came, which can cause all sorts of difficult lock contention problems, making free() much more expensive than malloc(). (Ask anyone who has written high-performance memory-intensive multi-threaded programs.)

    In some languages, like C, the situation is even worse. In structure-hungry programs, you can end up structuring your code around data lifetimes, which precludes you from using the most natural, maintainable and efficient algorithms. Garbage collection frees you from this, as the GCC people have discovered.

    I do recommend reading Paul Wilson's excellent survey paper on the topic. It answers a lot of your questions, though it's by no means the final word.

    --
    sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
  26. Bad examples by aminorex · · Score: 1

    The original post provided 3 examples of the supposed utility of programmer-controlled memory management and treated them as opposed to automatic garbage collection, but none of them served the original poster's argument: They were all examples of automatic variables being used with RAII, not to manage heap memory, but to manage non-memory resources by lexical scope. Cluestick sez: Languages with GC still have stacks. *Whack*.

    --
    -I like my women like I like my tea: green-
    1. Re:Bad examples by try_anything · · Score: 1

      If you accept automatically-destroyed stack objects in a GC language, you have to face the possibility of heap objects containing dangling pointers to destroyed stack objects. So there's a tradeoff even in that situation: you allow a certain class of memory errors, or you create a language feature that prevents garbage-collected objects from referring to stack objects.

    2. Re:Bad examples by hayriye · · Score: 1
      If you accept automatically-destroyed stack objects in a GC language, you have to face the possibility of heap objects containing dangling pointers to destroyed stack objects. So there's a tradeoff even in that situation: you allow a certain class of memory errors, or you create a language feature that prevents garbage-collected objects from referring to stack objects.
      A stack object may be treated as to be destroyed when goes out of scope at the beginning. But when a global variable is assigned to it, or used as a parameter to some method or function, then it may be qualified as subject to garbage collection
    3. Re:Bad examples by try_anything · · Score: 1

      I can think of some reasons why this would be hard, but none why it would be impossible. It does make it impossible to verify that a resource is properly disposed without verifying that none of the functions further out on the call tree accidentally maintain a reference. A nice feature of guaranteed destruction is that it allows me to glance at the function where the resource is allocated and quickly see that it can't be leaked.

      I would prefer that the type system enforce limitations to guarantee both safety and predictable destruction. How about this:

      * Every object has a scope, specified at its construction.
      * Some objects are garbage-collectible; others are guaranteed to be coextant with their scope. This is specified when the object is constructed.
      * Objects may only contain references to objects that belong to the same scope or a strictly larger scope.

      When an object is automatically destroyed as its scope exits, all valid objects that reference it are either eligible for garbage collection or schedule for immediate destruction, so there is no problem of integrity, except the inevitable problem that arises when destroying objects that reference each other.

    4. Re:Bad examples by cakoose · · Score: 1

      The scope qualifiers ("stack", "object", or "heap") apply to types, not to constructor invocations. Good defaults could alleviate the problem (and I, for one, think the payoff is worth it) but it's a lot of extra finger work. Think C++ const-correctness times 3 (at least).

      To avoid C's strchr(...) const problem, the qualifiers need to play well with type parameterization.

      The analysis required by the compiler is basically escape analysis. Currently escape analysis is usually a tranasparent optimization -- if it can't prove your object is bounded by the stack, it puts it on the heap. When scoping is part of the language, you'll get an error message instead and you have to go and fix your code (which could involve major restructuring).

      Finally, note that all this extra crap gives you a system that offers a much higher level of verifiablity than C++ does. If all you want is to be able to constrain non-memory resources to some lexical scope, then C#'s "using (...) { ... }" does the job. The only difference is that the resource's scope is explicitly delimited with braces. There's no technical reason the feature couldn't be changed to use the same implicit scope rules as C++. Garbage collection definitely doesn't get in the way.

    5. Re:Bad examples by cakoose · · Score: 1
      If you accept automatically-destroyed stack objects in a GC language, you have to face the possibility of heap objects containing dangling pointers to destroyed stack objects.

      Your point would be relevant if this thread were called "The Pros and Cons of Memory Safety". Yes, guaranteeing memory safety does make things harder. But if you don't require memory safety (and I don't see how you could, since C++ definitely doesn't provide it), GC mixed with stack objects works just fine.

    6. Re:Bad examples by try_anything · · Score: 1

      One interpretation of a type declaration is that it is a compile-time assertion that must be proven by the compiler. I imagine that making compile-time assertions about a function's impact on memory management would be very useful in some systems. This is a natural application for typing.

      Another idea: One of the qualifiers (perhaps the default) should specify that the compiler can choose whatever type it predicts will be most efficient, of the types it can prove valid. A dynamic compiler might make very good use of that freedom.

    7. Re:Bad examples by cakoose · · Score: 1
      Another idea: One of the qualifiers (perhaps the default) should specify that the compiler can choose whatever type it predicts will be most efficient, of the types it can prove valid. A dynamic compiler might make very good use of that freedom.

      Inference would work well for local variables and private functions, but you probably don't want any public API signatures to be inferred. So, you'd still have a lot of explicit typing to do.

      A dynamic compiler might make very good use of that freedom.

      What do you mean by a "dynamic compiler"?

    8. Re:Bad examples by try_anything · · Score: 1

      By "dynamic compiler" I mean a just-in-time compiler or any other compiler that has the opportunity to optimize code as it runs. What I had in mind is that some optimizations can't be performed unless the optimizer is able to examine code that is called from the code being optimized. A link-time optimizer would also be able to perform such optimizations, so a dynamic compiler isn't really necessary.

    9. Re:Bad examples by cakoose · · Score: 1

      Doing whole-program optimization wont help language-level scope requirements. The programmer, when he runs the initial compile (with "javac" or whatever), needs the compiler to acknolwedge that his "File" object's lifetime is limited to a given scope. A link-time optimizer could later go in and refine the scopes to make things faster, but the refinements aren't available for the programmer to take advantage of.

  27. not true by doug · · Score: 2, Funny
    The myth that garbage collection = poor performance is just that, a myth, and most likely started by people who associate Java's performance issues with garbage collection.
    Sorry, but I've thought GC was slow since the 80s. Java had nothing to do with it. - doug
    1. Re:not true by Pseudonym · · Score: 1

      Then I forgive you, because GC was slow in the 80s.

      --
      sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
  28. GC is DRY by PBPanther · · Score: 2, Interesting

    Not using GC requires that you to write code to free those resources repeatedly. That goes against the DRY (Don't Repeat Yourself) principle.

    I wonder how many of the people who use the "C++ model" bother to unit test that they have freed all their resources.

    1. Re:GC is DRY by try_anything · · Score: 1

      This isn't necessarily true. Take a look at some of the C++ examples posted in the thread. The C++ model is based around *never* (well, almost never) writing a line of code to release any resource. If you type

      scoped_ptr foo(new string);

      you never have to worry about deallocating or leaking the string. This makes RAII quite compatible with DRY. C++ memory management still leaves much more scope for errors than garbage collection, though.

  29. C has problems too by countach · · Score: 2, Informative

    C memory management is not completely deterministic either, since a fragmented heap will not always take the same amount of time to allocate in. To make it completely deterministic you would have to pre-allocate objects. But if you're going to do that, you could do it in a GC language and turn the GC off.

    1. Re:C has problems too by be-fan · · Score: 4, Insightful

      It's frightening the allusions programmers have about manual memory management. They seem to think that malloc() and free() are cheap functions, when in reality they can take hundreds of clock cycles. They think that malloc() is deterministic, when in reality, a badly fragmented freelist can cause most malloc() implementations to traipse through the entire heap, just like a GC.

      The weirdest thing is C++ programmers. They freak out about every single cycle, but modern C++ idioms push the use of smart pointers, which are usually quite slow compared to a good generational GC.

      --
      A deep unwavering belief is a sure sign you're missing something...
    2. Re:C has problems too by dkf · · Score: 1
      It's frightening the allusions programmers have about manual memory management.
      I'm sorry, but that word does not mean what you think it means.
      --
      "Little does he know, but there is no 'I' in 'Idiot'!"
    3. Re:C has problems too by be-fan · · Score: 1

      Or, you could give me the benefit of the doubt and assume it was a typo (which it was).

      --
      A deep unwavering belief is a sure sign you're missing something...
  30. I went to a job interview . . . by erikharrison · · Score: 1

    I had this job interview where I was asked if I started a new project right now what programming language would I write it in.

    I said "That would of course depend heavily on the project"

    This got me the job, because I was the only person who didn't answer "Java" or "PHP" - a clear indicator that the prospective employee was either feeding you the line they'd gotten in CSCI 102 at the local university, or reacting against that line.

    The same thing about garbage collection. Come on, if I'm writing a web application with 10000 concurrent users, I'm going to write in Perl or PHP, because I can throw hardware at the performance problems, and the hell with stupid memory bugs in an app difficult to run in a debugger or profiler.

    And if I'm writing a device driver? C. Duh. I don't want the compiler doing anything stupid with my memory mapped registers.

  31. There's more than one way to skin a cat. by Anonymous Coward · · Score: 2, Informative

    Having used languages with and without garbage collection, my view is that
    garbage collection is often very nice... but I don't really mind the "lack" of garbage collection in C and especially don't miss it in C++.

    My opinion is that it takes some effort on the programmer's part to learn to use C safely. I'm not sure why, but this answer seems to suprise some people. Do they seriously expect that in the real world-- of software or of anything else-- that they should be able to pick up any tool they want and understand how to use it well right away? Appearantly so, but it's pretty silly, isn't
    it?

    C++ and C are like very sharp carving gouges: It's up to you to learn how to use them properly, to hone them peridically, and to build safe habits. You need to do this in any language that you use, but the sharper the tool the more important it is to bear this principle in mind. A lot of people try to pick up these sharp tools, and then blame the gouge when they've cut themselves. It's no suprise, because they did not take the time to learn to be careful.

    In my view your best bet for using a programming language safely is to develop
    certain habits and adopt idioms that cause you to simply not write code with some types of errors. In the case of resource-freeing errors, when you open a door, you must remember to close it. It's not complicated, but you have got to turn it into a real habit, something you just do-- and it follows that there will also be some patterns that you should train yourself to just never write. Give it a go (and give it some time).

    That will go a long way, but I'm afraid that there's some bad news: even that is not enough. I've been writing software in C for 17 years now, and although without a doubt I write fewer errors than I used to, I still do not produce error-free programs. Eventually, I make plenty of mistakes. Complexity does that.

    Some very good news: Memory management in C++ is so nice that very frankly I do not miss /either/ garbage collection or C-style memory management when I am using it. (And of course, you can use either of those with C++ just fine.) There are all kinds of tools and patterns to help you out, although again it's going to be up to you to use them and make a habit of it. There's the "resource aquisition is initialization", smart pointers (built into the standard library, provided by Boost, and roll-your own), new and delete, malloc() and free(), statically allocated memory, and garbage collectors for you to link in. Take your pick! Use the right one for the job.

    Bjarne Stroustrup explains all of this extremely well. Here's a link or two to his FAQ and what it has to say about C++ and garbage collection:

            http://www.research.att.com/~bs/bs_faq.html#garbag e-collection
            http://www.research.att.com/~bs/bs_faq2.html#memor y-leaks
            http://www.research.att.com/~bs/bs_faq.html#advanc ed

    Think about it for a while. Remember that memory is only one kind of resource that we need to manage. It's up to you to ferret out and apply the tools available to you.

    If you want a garbage collector, why not use one? But it's not the only way to achieve the ultimate goal of producing reliable, efficient software.

  32. Personally... by g-san · · Score: 3, Funny

    I prefer garbage collection. At most, I take the cans to the edge of the driveway and some guy in a noisy truck with a cool robotic arm just hauls it away. Yeah, there is a landfill somewhere that isn't good for the overall environment but I accept that tradeoff. I also don't throw old car batteries into the trash.

    Sure the hell beats me keeping the trash around, remembering where it is, and putting it in my truck and hauling it to the heaping landfill myself. I'm not here to manage trash, I'm here to get something done.

    Is this post about programming?

  33. False dichotomies by Eric+Smith · · Score: 3, Interesting
    Some of the cited advantages of not using garbage collection are red herrings. For instance the "controlling access to files and similar resources" by RAII works fine with garbage collection. In most cases, the compiler can determine by static analysis that a particular object is allocated within a scope and no referenes are propogated upward out of scope, and can remove the reference so the garbage collector will deallocate it (possibly calling a destructor). Depending on the type of GC and its implementation, the compiler may generate code that forces the object to be deallocated immediately.

    For cases where static analysis can't do this automatically, it isn't that hard to use a design methodology that achieves the same result; it's certainly still much easier than doing manual allocation and deallocation and ensuring that the deallocation is done (or not done) correctly in all cases.

    And if you are using a reference-counting GC, or a hybrid GC that includes reference-counting, you don't have to do anything special at all.

    The same applies to the claimed mutex and error message disadvantages, since those are just specific uses of RAII.

  34. Java GC != No leaks by samjam · · Score: 2, Insightful

    Right now someone I know is trying to track down a Java memory leak.

    No doubt some reference is left in a persistent collection of some sort (hash, list, array, etc)

    Just As C/C++ programmers must remember to free when done, so Java programmers must remember do undo such "life maintaining" references when they are done.

    Sam

    1. Re:Java GC != No leaks by the+eric+conspiracy · · Score: 3, Insightful

      Right now someone I know is trying to track down a Java memory leak.

      Yes, but it is unlikely that somebody you know is trying to track down a Java double free error.

  35. Re:Memory Access vs. Memory Allocation Re:Situatio by ultranova · · Score: 1

    People seem to have confused Memory Access with Memory Allocation. Neither GC nor PC (programmer collected) should allow memory accesses on out-of-scope data. GC just delays when that out-of-scope data gets freed for reallocation.

    Not inherently. It is perfectly possible to write a GC implementation that stores data that can only be accessed in a certain scope into the stack, and frees it automatically and immediately when the scope exits. From what I've understood, Sun's upcoming JVM does just this.

    Garbage collection versus manual collection really only applies to objects that get passed out of the scope they were created in.

    --

    Forget magic. Any technology distinguishable from divine power is insufficiently advanced.

  36. Garbage collection efficiency overstated by butlerm · · Score: 3, Interesting

    This is a common claim, but it is an apples to oranges comparison. No one (including the compiler) dynamically allocates objects in C/C++ when they can place them on the stack instead. Garbage collected languages like Java, on the other hand, require practically everything to be managed on the heap.

    In addition, an array of objects on the heap requires only a single memory allocation in C or C++, where Java has to allocate and track each separately. As one luminary once said, "C++ is better because there is less garbage to collect."

    That might be acceptable, but the worst part is random application pauses of arbitrary duration for garbage collection. Unless that problem can be resolved, garbage collected languages will be always be a poor match for latency sensitive applications, even where the net throughput is otherwise adequate.

    1. Re:Garbage collection efficiency overstated by swillden · · Score: 4, Interesting

      No one (including the compiler) dynamically allocates objects in C/C++ when they can place them on the stack instead.

      Are you certain of that? Here:

      void foo()
      {
      //...
      auto_ptr<Foo> f(new Foo);
      //...
      };

      What would the compiler do? What *could* it do, if it were smarter? And have you really never seen any code that does this? Or written it?

      Lots of C and C++ programs dynamically allocate many objects that could be heap allocated. In particular, many C++ objects that are placed on the stack immediately allocate storage on the heap. Think std::string. Many programmers do make an attempt to allocate as much on the stack as possible, but I think most don't really consider it. And keep in mind when I say this that I've been writing C and C++ (mostly C++) professionally for nearly 15 years -- I've seen more than a little code.

      Garbage collected languages like Java, on the other hand, require practically everything to be managed on the heap.

      Interestingly, Java does *not* require that at all... it's just the most obvious way to implement it. In fact, I read a while back that the next generation of Java compilers will perform escape analysis, looking for objects whose lifetime is associated with a stack frame. Here's a link. When they find such an object, it will be allocated on the stack. If such an object creates other objects, as long as the analysis can prove that their lifetimes are also frame-associated, they will also be allocate on the stack.

      The same analysis will often allow Java objects and their sub-objects to be allocated as a single block. Since the compiler can see that the constructor of class Foo always allocates objects of Bar and Baz, all of fixed size, it can allocate a single block, just like a C++ compiler would be able to for a class like:

      class Foo
      {
      // ...
      Bar bar;
      Baz baz;
      };

      The same sort of analysis should also allow your other point to be addressed: An array of objects can be allocated as a single block. The compiler can recognize code like:

      Foo[] f = new Foo[n];
      for (int i; i < n; ++i)
      f[i] = new Foo;

      And allocate a single block that is n*(sizeof(Foo)+sizeof(Bar)+sizeof(Baz)) in size, and if 'f' has a stack-associated lifetime, allocate the whole pile on the stack.

      All of the above is still theoretical, of course, but it's coming quickly.

      That might be acceptable, but the worst part is random application pauses of arbitrary duration for garbage collection. Unless that problem can be resolved, garbage collected languages will be always be a poor match for latency sensitive applications, even where the net throughput is otherwise adequate.

      As I pointed out in my previous post, whether or not that problem exists depends on the GC implementation. Incremental GCs keep the pauses small, and there are GCs designed for real-time usage that further guarantee maximum latencies. It's worth pointing out also that normal malloc() and free() implementations don't provide any run-time guarantees. Real-time code that uses a heap uses special versions that do provide guaranteed latencies, at the expense of worse average performance.

      --
      Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.
    2. Re:Garbage collection efficiency overstated by flux · · Score: 1

      And what happens if you call a method that might store the pointer for later perusal, but the method that made the call finishes? The calling method can no longer simply pop the stack and call the associated desctructors at finish, because there might exist pointers to them.

      Doing this in C/C++ is considered a bug (dangling pointer), therefore You Don't Do It - instead, you get to decide and tell the compiler if the variable may be stored to the stack or not. In Java you might write code such as above and expect it to always work legitimately, so the optimization you mention will require very extensive analyzing (due to lack of developer hints) of the methods that are called - and it needs to be done on the bytecode level because sources to external libraries might not be around, but I imagine that might actually simplify things - that is, until someone makes a call to a C-library.

      I don't think it is as easy as you make it out to be.

    3. Re:Garbage collection efficiency overstated by /ASCII · · Score: 1

      Escape analysis is by no means easy. And it is also the case that it is easy to see that an object can not escape, it is much harder to proove it. But on the other hand, escape analysis can sometime work succesfully in cases where manual coding without using the heap would be very cumbersome, such as when using autopointers or similar, when inlining blocks of code in different contexts, some of which require heap storage, etc.

      --
      Try out fish, the friendly interactive shell.
    4. Re:Garbage collection efficiency overstated by Breakfast+Pants · · Score: 1

      "That might be acceptable, but the worst part is random application pauses of arbitrary duration for garbage collection. Unless that problem can be resolved, garbage collected languages will be always be a poor match for latency sensitive applications, even where the net throughput is otherwise adequate."
       
      Malloc and free are also non-deterministic.

      --

      --

      WHO ATE MY BREAKFAST PANTS?
    5. Re:Garbage collection efficiency overstated by Pseudonym · · Score: 1
      Many programmers do make an attempt to allocate as much on the stack as possible, but I think most don't really consider it.

      Multi-threaded programmers do. Allocating an unbounded (at compile time) amount of data on the stack is considered very bad practice when the size of your stack is limited.

      --
      sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
    6. Re:Garbage collection efficiency overstated by swillden · · Score: 1

      Multi-threaded programmers do. Allocating an unbounded (at compile time) amount of data on the stack is considered very bad practice when the size of your stack is limited.

      Better to say "programmers in stack-limited environments do". Some multi-threaded programming environments don't have (practical) stack size limitations, and some single-threaded environments do.

      For an example of a multi-threaded environment without real stack size limitations, I've written some multi-threaded Linux programs that use mmap() to allocate a huge stack for each thread. Since mmapped memory is purely virtual and unbacked by RAM or disk until it's actually used, the net effect is of unbounded stack sizes. Well, more precisely, of stack sizes that are bounded by a limit that is ridiculously high, especially on 64-bit systems.

      For an example of a single-threaded environment with stack limitations, consider nearly any embedded system. One very extreme example: I know guys who regularly write code for environments with a fixed-size stack measured in tens of bytes. They use all global variables so the stack contains nothing but return addresses and they keep the call trees very shallow. One platform in particular has a "stack" that isn't kept in RAM at all, but in CPU registers. Three of them :-) Yeah, those guys think about where to allocate memory...

      --
      Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.
    7. Re:Garbage collection efficiency overstated by tengwar · · Score: 1
      What would the compiler do [with auto_ptr example]? What *could* it do, if it were smarter? And have you really never seen any code that does this? Or written it?

      You seem to be suggesting that in this case "new Foo" should allocate on the stack. This would break if the underlying object was intended to survive this function invocation, which could happen if f.release() were called.

    8. Re:Garbage collection efficiency overstated by swillden · · Score: 1

      You seem to be suggesting that in this case "new Foo" should allocate on the stack. This would break if the underlying object was intended to survive this function invocation, which could happen if f.release() were called.

      In which case a compiler smart enough to perform this optimization would also be smart enough to notice the release() call (or, more precisely, notice that the pointer value "escapes" from the function boundaries) and would therefore not allocate it on the stack.

      --
      Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.
    9. Re:Garbage collection efficiency overstated by tengwar · · Score: 1

      Yes, but how often are you going to allocate an autoptr and not pass it to a function? The normal case is that it will be used outside the function.

  37. For the record by Tune · · Score: 1

    I don't know if TurboPascal is GC or not, but I don't remember explicitly allocating and freeing variables, so I guess so.

    Pascal doesn't do automatic gabage collection, it provides Alloc and Free functions for dynamic memory management. Apparently you only bothered to write code using global and local (stack allocated) variables. But rest assure that any trivial piece of linked list code in Pascal has you doing the deallocation manually.

  38. I Shouldn't Have to Change Toolsets by oldCoder · · Score: 1
    I may need to write some code with manual memory allocation, and I would then like to write the rest using GC coding methods.

    I shouldn't have to change languages, change IDE's, and change the rules of disambiguating overloaded operators in order change coding paradigms.

    Granted, you may not want to mix paradigms in the same thread, but having a multi-threaded app with some threads use malloc/free or C++ new-delete and other threads use GC seems entirely reasonable.

    Even hard real-time systems often have portions of the code that can live with the occasional GC pause.

    I shouldn't have to change languages to change paradigms, just declare a threads memory type and be consistent. Inter-thread communication will have to accomodate this, of course.

    Java could have made much more of a contribution if it had done this. And C++ could have supported a standard interface to GC earlier on, to support GC code in C++. MS C++ now allows coding for managed code, but it's a little late in the game for C++. And the managed environment generates IL, not machine code, so "Managed code" is not exactly equal to "Uses GC".

    --

    I18N == Intergalacticization
    1. Re:I Shouldn't Have to Change Toolsets by Anonymous Coward · · Score: 0

      .Net allows you to mix Garbage-collected managed C++ code with non-garbage-collected unmanaged C++ code at will. Well, if you take the time to learn how,

      Of course.. it also allows you to also dump in other languages, but C++ is the only one it allows to run unmanaged /at the same time/ as managed. Usually you have to pick one. mC++ in .Net doesn't make you.

        Cheers.

  39. C != manual memory management by Anonymous Coward · · Score: 0

    Okay, so in C / C++ you might have to malloc() and free(). But the C libraries still manage the memory for you (or the operating system does, depending on what/how you're coding).

    Memory management is about much more than specifying when you grab a chunk of memory and when you release it. It's also about managing fragmentation of memory, for example. GC handles this for you and therefore can optimize it in a way that would be harder to do in C.

    Worrying about these things does not make a good programmer. A good progammer delivers software that works to a reasonable extent within a reasonable timescale. That may only sometimes mean having to worry about these things. 'Works' depends on what you're trying to achieve. If it takes you twice as long because you unnecessarily used C++ instead of Java, then that's not good programming practice.

  40. Refactoring and Program Evolution by angel'o'sphere · · Score: 1

    Successfull programs evolve over time.
    So they get refactored. Classes get reused at unexpected places. References to objects are kept on places where it was not anticipated. Calling delete now is unapropritated at the old point as it can't take the new references and the changed lifetime into account.

    So the memory management needs to get refactored just because you "reuse" a class?

    Simple example (controverse because it shows where GC leads to problems also :D ) :
    For some reason you implement a cash for a certain type of objects.
    In a non GCed language everywhere where you delete the objects you need to tell the cash to drop it first.
    Now that means you have to change existing code and write new test cases. And it means you can not assign different programmers to different tasks. You also can renot use the original class without the cash now.

    However in GCed languages the cash influences the lifetime of the objects, so you need WeakReferences as wrappers around the obejcts in the cash.

    Nevertheless, bottomline GCed languages give more flexibility in program evolution, or simply refactoring during ordinary development. Classes are easyer to reuse as you can change to a new object lifecycle without changing the original classes sourcecode.

    angel'o'sphere

    --
    Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
  41. Depends on the job. by Kaenneth · · Score: 1

    For short-lifetime, stateless programs, like queries, scipts, macros, and such GC is fine because if has a finite end, at which everything can be cleaned up together.

    But for longer running programs which launch other programs like root processes, server processes, and such; they might hang around long enough to run out of memory.

    To me the crux is, how does a garbage collector itself allocate memory? Somewhere down the line something has to keep solid track of resources, GC is an option for many subsystems, but regular allocation is a requirement at some point.

    You might use a car iunstead of walking to get to a lot of places, but you have to walk to the car first.

    1. Re:Depends on the job. by convolvatron · · Score: 1

      umm. it works the same as malloc. you get raw
      pages from the operating system, and you have
      to spend some of that space keeping track of
      whats free.

      one (overly) simple approach is to keep a list
      of 'partially allocated' pages for each size
      of interest (2^n). in each page there is a
      freelist and free count. an allocation is thus
      two indirections in the common case. a completely
      empty page gets given back to the os, or put
      on a list of unassigned pages. multi-page objects
      are handled differently (always as a multiple of
      the page size)

      there are of course many other approaches. the basic
      literature is very accessible if you're interested.

  42. VM aware GC by renoX · · Score: 2, Interesting

    A paper I've found interesting is on a GC which communicates with the VM systems to avoid putting too much load on the VM system.
    It needs a modification of the VM, but IMHO this is better than having to handtune the memory used by the GC. (Note: I'm not an expert in GC)

    http://www.cs.umass.edu/~emery/pubs/04-16.pdf

  43. Evolution by kallax · · Score: 1

    Well yes it does depend on the project, but even more so on the programmers involved. Memory leaks breaking applications are a visual indication of stupidity, carelessness or timescales that are too tight. GC allows total idiots to masquerade as anything they like from systems programmer to xyz expert. The problem then is that although their code works (with the help of GC) it probably does not perform the correct function. I cannot begin to say how many financial reports I have found careless careless mistakes in; did the programmers just get lazy from things like GC? Even at the VS2005 launch I am amazed at the questions that developers are asking: at least 50% do not understand how a forms or web application works: proof of that was the reaction to the security session at DDD in Reading. Managed code, GC & everything else from weed to cola all has friggin advantages & disadvantages. In short: don't climb into the driving seat unless you know what you're doing.

    1. Re:Evolution by angel'o'sphere · · Score: 1

      Your points you make in yoour comment IMHO have nothing to do with GC but with point and click IDEs.

      If you can point and click a simple web applicatioin without knowing anything about HTTP, Web Servers and/or HTML and browsers, you wont feel the need to learn anything about that.

      And as you dont know anything and dont learn anything you fail to program as soon as point and click is at its limits ...

      Its the same with VB and forms ...

      Managers doing their own Excel Forms programming are those who dictade deadlines and programming scopes, as they think everything as easy as even they can program :D

      angel'o'sphere

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
  44. As you say, it all depends on context. by Richard+Steiner · · Score: 1

    In the mainframe-based online transaction application environment where I work, each program is given a fixed block of memory to play with. Period. After the program terminates, that memory is usually freed, but often a transaction has either its code or its data memory area(s) locked into core to speed up program load times (it remains resident but idle until the next time the program is activated).

    Transaction programs are event-driven entities, though, and they have very short lifetimes -- they are loaded in response to a specific query, they perform their task (usually in a fraction of a second), and they terminate, returning control to the transaction monitor.

    Performance (as in "reponse time") is one of the key design criteria for such an environment. The whole idea is to break an application into a series of discrete transactions, each performing its predefined task and then terminating. Most of the time a task consists of reading a series of files and creating a display screen, or parsing a data entry screen and saving the result to a file or files.

    All in all it's quite slick, and it completely avoids the kinds of traps that one sees in the world of typical PC or UNix applications (where a program remains resident for many minutes or hours and has to do dynamic memory allocation/deallocation on its own).

    --
    Mainframe/UNIX Bit Twiddler and long time Windows/Linux Hobbyist.
    The Theorem Theorem: If If, Then Then.
  45. Re:Memory Access vs. Memory Allocation Re:Situatio by Jerf · · Score: 1

    People seem to have confused Memory Access with Memory Allocation. Neither GC nor PC (programmer collected) should allow memory accesses on out-of-scope data.

    This is why I mentioned I was talking real-world, not theory. I can conceive of a "safe" (out-of-scope data not accessible by any in-language construct) language that uses manual allocation. But I am aware of no such beast, which doesn't prove it doesn't exist but is pretty strong evidence that it's not very popular if it does.

    And going back to the original post, even if it did, it would not be the manual allocation that would be the source of the security, it would be the safety of the language, so OP was still off.

  46. Find the middle ground by Anonymous+Brave+Guy · · Score: 1
    You can't ignore the complexity of manual memory management.

    A lot of posts in this discussion almost imply that there is 100% manual memory management, or some sort of super-generational-buzzwordy-GC, and nothing in between. That simply isn't the case.

    I write C++ for a living. I work with intricate, graph-like data structures, using performance-sensitive algorithms, with pointers all over the place. And yet I can't remember the last time I had to use the delete operator, nor any sort of super-ref-counted-smart-pointer. We just have a simple, effective ownership scheme, and deterministic destruction of the owning objects guarantees everything is always cleaned up completely and promptly.

    There is no magic. There is only knowing which tool to use for which job.

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
  47. People keep confusing concepts by Anonymous+Brave+Guy · · Score: 1

    It's not just you. A lot of people in this discussion are confusing fundamentally different concepts whose implementations often happen to coincide.

    In particular, whether or not something is ever cleaned up is different from whether or not it is cleaned up promptly. Also, releasing memory is not the same as destroying/finalising an object that happens to be stored in that memory.

    Garbage collection addresses exactly one of the four possible combinations: making sure that memory is always released.

    The main advantage of C++'s RAII idiom covers the opposite combination: making sure that objects are destroyed promptly. (As it happens, in C++ the underlying memory is also guaranteed to be released after the destruction of the object when using automatic variables, so we're actually covering two of the combinations here.)

    The fact that the latter can be used to guarantee the former, but the converse does not hold, is why RAII is a much more powerful tool than a straightforward GC. The fact that the former works automatically while the latter requires some coding skill is why a simple GC is a more reliable tool for average programmers than RAII.

    As always, you have to look at what you've got to do and who's going to be doing it, and then pick an appropriate point on the power-safety spectrum.

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
  48. Why do C++ people use the acronym RAII "resource acquisition is initialiation" to talk about when the object is uninitialized?

    Because the concept is more fundamental than merely "resource release is destruction", although the latter is arguably the most important aspect of it.

    What you're doing in C++ is tying the period between allocation and release of a resource to the lifetime of an object. If you like, the resource-owning class's invariant conditions include the fact that the resource is allocated correctly.

    That means that allocating the resource in the constructor is quite fundamental. If the allocation fails, the constructor should fail. If it does so in the idiomatic way -- throwing an exception -- then the resource-owning object never exists, and can't inadvertently be misused because its name will be inaccessible.

    Similarly, as long as the resource-owning class is instantiated as an automatic variable, the deterministic destruction when it goes out of scope ensures that the allocation of the resource can't outlast the owning object either. Again, it also ensures that once the resource is no longer allocated, the name of the owning object is no longer accessible.

    In between, you have a valid object, which can present whatever interface the programmer deems useful in order to access the resource it owns, and which can hide any handle necessary to refer to that resource.

    All of this is possible because of the interaction between C++'s scoping rules, automatic variables, deterministic destruction and exceptions. Since Java lacks at least two of those, it's not possible to get the main benefits of RAII in the same way.

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
    1. Re:RIAA by Anonymous Coward · · Score: 0

      Yes I understand what RAII is, I was pointing out that the name is misleading. You can allocate the resource when the object is constructed in Java, if you want, just like in C++ (and throw an exception if you want). You can release the resource when the object goes out of logical scope, by calling the finalize method manually just like you call delete in C++. What you can't do is automatically release it when the object goes out of lexical scope. That's why I suggested lots of more sensible names.

  49. Bottom line is by TheSkepticalOptimist · · Score: 0

    If your a serious programmer, learn how to manage your own memory. With the exception of C++, most other development languages are intended for rapid application development senarios. Typically people involved in this level of development are not native programmers, but people from other career paths that got into programming out of necessity for the job rather then a real desire to develop software for a living. I am NOT saying that these people are not skilled in what they do, just that programming wasn't their first love or forte. They haven't spent years learning the ins and outs of software development, or have worked years honing their skills. Memory management is one of those things that requires discipline. You need to do things in a specific way, and if you don't, you leak memory and cause program/OS instability. Only after years of dedicated programming does one learn how to write code that does not cause memory leaks (and even then it can easily trip you up), you learn the skills and tricks to control the allocation and deallocation of memory. People using RAD tools or languages with garbage collection are focused on the end product rather then skilled design. The limitations of disciplined programming eat into their ability to get the job down quickly and efficiently, they didn't spend years learning to program, they need to get the job done in a few weeks or months. Garbage collection in these RAD tools means they don't have to worry about highly disciplined programming. From what I have seen, ANY language with garbage collection is typically NOT used for high performance applications. They are used for web or database front ends, intended to be a UI layer between data and the user. I have never seen a Visual Basic, Java, or C# language used for scientific calculations (nothing serious that is), or high performance software where speed is a concern. In any regard, if all you ever intend to do is to make UI front ends for web services or databases, then any language with garbage collections will suit you fine, you don't have to worry about the finer points of developing software and can simply focus on the final product rather then the details on how to get there. The extra overhead garbage collections imposes on these higher level languages will not be noticed or undesirable in the final product. But, if there is a chance you may need to develop a high performance application, or if you think you may be developing in C++ or another non-managed language, learning how to effectively allocate and deallocate memory is an invaluable skill to learn.

    --
    I haven't thought of anything clever to put here, but then again most of you haven't either.
  50. Re: Old Adages by some+guy+I+know · · Score: 1
    This goes back to the old adage: "Programmer time is more valuable than processor time."
    That adage isn't that old.
    Thirty or forty years ago, the opposite was true.
    --
    Those who sacrifice security to condemn liberty deserve to repeat history or something. - Benjamin Santayana
  51. Lisp idiom by Nicolay77 · · Score: 2, Interesting

    In lisp that would be using the unwind-protect macro.

    Notice that this is totally unrelated with memory management.

    So yes, it IS possible to have our cake and eat it too.

    --
    We are Turing O-Machines. The Oracle is out there.
    1. Re:Lisp idiom by Anonymous Coward · · Score: 0

      I'm a total Lisp n00b, so I may not be best to discuss it, but when I saw unwind-protect my jaw dropped. It's totally rad. You don't have to have separate cleanup code on every control path, this one construct covers you for returns, throws, exceptions, and plain old getting done with the block. It'd be great to have something like that in Java. It's obvious that lisp is the result of years of actual use by real programmers who weren't afraid to innovate when it made their lives easier, unlike these other languages that were designed by committee (c#, I'm looking your way...). It's sweet. Too bad they haven't standardized some basic library functionality like networking and threads across vendors. Then it'd be poised to take off again.

  52. The first GC language ever, does it... by Nicolay77 · · Score: 1

    As I told in another post, in Lisp you can use the unwind-protect macro to perform this "pattern".

    This is used to perform file access, database access and so on.

    But in the languages you use, you need a compiler-interpreter update from the vendor/implementor to fix that.

    --
    We are Turing O-Machines. The Oracle is out there.
    1. Re:The first GC language ever, does it... by try_anything · · Score: 1

      I'm familiar with unwind-protect; it has essentially the same form as a try/finally clause in Java. It's an improvement over simple try/catch, and you only have to remember to release your resources in one place, but you still have to explicitly release your resources, which makes it different from RAII and easier to get wrong.

      You can actively undermine the RAII idiom in some cases by performing dangerous operations on the resource object, but you can't simply forget to release the resource, since one line of code specifies when to acquire the resource and when to release it. unwind-protect requires two lines and allows you to leak the resource by forgetting the second line.

    2. Re:The first GC language ever, does it... by Nicolay77 · · Score: 2, Informative

      You're absolutely correct, however...

      You don't usually use unwind-protect directly. You use a macro that uses it underneath. Like the with-open-file macro or the with-database macro of CLSQL.

      Like this:

      (with-open-file (stream "/some/file/name.txt")
          (format t "~a~%" (read-line stream)))

      You can never forget to close the file in that code.

      Having to use unwind-protect directly is just another case of the "human compiler" pattern at work. It's very unusual to have to use database access or file access or something like that just once in your program, so writing a macro is a good investment.

      --
      We are Turing O-Machines. The Oracle is out there.
    3. Re:The first GC language ever, does it... by try_anything · · Score: 1

      Ah, I see. A Lisp programmer is never stuck with redundancy - I should have remembered that!

  53. Re:RAII is a bad reason for manual memory manageme by GebsBeard · · Score: 1

    Raw speed. Malloc a huge chunk of memory. Custom cut one or more items out of the huge chunk, manually managing byte alignment of the objects to ensure portability between different chipset architectures. This is what most people refer to as a "custom allocator" (possibly also a pool or slab allocator) and its performance is vastly higher than an equal number of new's in a GC language. But wait! You don't have to actually free anything once you're done (no memory leaks), you just do a bulk free of the original memory slab. Or not, you can just reuse the memory slab for a new group of objects. Manual memory management gives flexibility that no GC language ever will. If you don't need the flexibility then fine, you can use a GC language and reap the benefits. Just don't complain when you're shopping around for a product and find one that is 5x the speed of its GD'd competitors. Then you the customer are forced to pay the price for programmer laziness and/or convenience.

  54. Lisp again... by Nicolay77 · · Score: 1

    As I said in another post, GC and the automatic release of a resource can be managed independently (when the resource is not allocated memory). It is just a language design issue.

    In Lisp you have GC, and you have the unwind-protect macro that does the "RAII" idiom, and they are totally independent one from the other.

    Having said that, I like the objects-in-the-stack feature of C++.

    --
    We are Turing O-Machines. The Oracle is out there.
    1. Re:Lisp again... by GileadGreene · · Score: 1

      Lisp's unwind-protect is the prototypical "RAI as Invocation" idiom. Plenty of other languages implement it though (Haskell and ML come to mind). The presentation at C2 is pretty generic, and not tied specifically to Lisp.

    2. Re:Lisp again... by Nicolay77 · · Score: 1
      The presentation at C2 states this:

      "Of course, this is not the easiest technique to use in Java, C#, and C++, [...] Thus it is not surprising that this technique works extremely well in the LispLanguage, and moderately well in the PythonLanguage."


      So, well, we are both right.
      --
      We are Turing O-Machines. The Oracle is out there.
  55. Closures and objects by Nicolay77 · · Score: 1

    Closures and objects are quite different, but they can be used (almost) the same way.

    However, I think that you don't need an anonymous class to implement an algorithm that is originally conceived using closures. A normal class is enough and easier to use.

    The good thing about closures is that you write less code, and that code is usually more elegant.

    I say this because I generally try new algorithms in Lisp, and when they are working just perfectly, translate the algorithm to C++ or php or whatever I'm using.

    --
    We are Turing O-Machines. The Oracle is out there.
  56. Re:RAII is a bad reason for manual memory manageme by GileadGreene · · Score: 1

    Sure. But the original question was about reasons for manual management other than performance. Plus, as others have pointed out in this thread, the performance of GC-based systems is not necessarily any worse than that of a manually managed memory (even using custom allocators) depending on how the GC is used and how complex the things you're doing with allocated memory are. More importantly, for many applications GC is not the performance bottleneck, even when it does have lower performance than a manually managed solution. You have to look at the complete system, not just individual features of it.

  57. Re:RAII is a bad reason for manual memory manageme by Arandir · · Score: 1

    But what if you need/want the initialization idiom?

    --
    A Government Is a Body of People, Usually Notably Ungoverned
  58. simple rule of thumb by Surt · · Score: 1

    Use GC unless you know precisely why you're not doing so. And even then, double check to make sure you're right.

    --
    "Who is the Journal of Quantum Physics going to believe?" --Stephen Hawking
  59. The language you which for is allready there. by krischik · · Score: 1

    Hi,

    Have you ever heard of Ada? No, then read:

    Easy (at wikibooks):

    http://en.wikibooks.org/wiki/Ada_Programming/Types /access

    Detailed (ISO/IEC 8652:1995(E)):

    http://www.adaic.com/standards/rm-amend/html/RM-13 -11.html

    All you wanted - especially the savety part. Still you can also use an "access all" if you need more flexibility.

    The thing I like about Ada it that it comes with of lot of savety features which I can all switch off if I need to.

    Martin

  60. Re:RAII is a bad reason for manual memory manageme by GileadGreene · · Score: 1

    The invocation idiom does the same thing as the initialization idiom. It just implements it in a different way. A way that doesn't depend on whether or not you are using GC. So why would you need/want to use the initialization idiom?

  61. Some confusion here... by X · · Score: 1

    So, I see the poster has recently picked up RAII. ;-) Yup, it's lot's of fun.

    However, what RAII provides is a way to do lexically scoped resource lifecycles. It's really handy for common cases, but it turns out that for complex situations it gets quite ugly, becuase it's hard to be certain that you are really "done" with a resource simply based on lexical analysis (hence why people end up doing things like reference counting).

    Arguably, a better solution would be for the runtime to have knowledge of how to manage all types of resources, not just memory but file descriptors, disk space, database connections, etc. Indeed, a lot of the code in complex systems is all about implementating algorithms for generically managing such resources and then providing an abstracted interface to said algorithms.

    However, in the imperfect, real world of programming, it's tough enough to find a runtime that can intelligently manage memory, let alone other resources. In systems that do have automatic memory management, it is still possible to have lexically scoped resource management (C#'s "using" clause as an example) for other resources. So, the resources get freed up when you drop out of your lexical context, but the memory associated with those resources gets managed seperately by the runtime's automatic memory manager.

    So, going with automatic memory management is really orthogonal to using something like the RAII paradigm for managing resources.

    --
    sigs are a waste of space
  62. Re:RAII is a bad reason for manual memory manageme by Arandir · · Score: 1

    An idiom is a way of thinking. Initializing resources versus invoking resources are two different ways of thinking about resources. Neither one of them is wrong. What is wrong is to limit yourself to only one way of thinking.

    The RAII link used files as an example. In most such cases invoking makes sense, because that's how you use a file. Rarely do you actually "initialize" a file. But you do it with data all the time. Getting rid of initialization is to get rid of object constructors. Even in vanilla C your data is conceptually composed of objects that need initialization. Since there is a high correspondence between data and memory in most software, it makes sense to allocate memory with the initialization idiom. (But not always, which is why you should never limit your way of thinking).

    --
    A Government Is a Body of People, Usually Notably Ungoverned
  63. Re:RAII is a bad reason for manual memory manageme by GileadGreene · · Score: 2, Insightful

    As some of the folks at C2 pointed out in the originally linked references, RAIInitialization is a misnomer anyway (as is RAIInvocation - but that was created in response to the other RAII). Most of what we're talking about here is (despite the name) finalization. That's the part that conflicts with GC. No one's saying that we should eliminate initialization or constructors. The point is that using the RAIInit idiom to handle resource finalization is not a good argument for manual memory management, because the RAIInvoc can produce the same finalization effects without producing any conflict with garbage collection.

  64. Re:RAII is a bad reason for manual memory manageme by Arandir · · Score: 1

    Except that RAIInvoc isn't a part of most languages, meaning I have to write them myself. Don't forget, RAIInvoc isn't just for memory, it's used for all resources, including files, threads, etc. The invocation idiom is a part of some languages, but not all. For those myriad langauges for which it is not a part, are we supposed to do all the extra work of implementing it?

    p.s. So where's the big push for file handle collection? If deallocating memory automatically is necessary, then where is the concern over closing files automatically? What makes calling free() so much more evil than calling close()?

    --
    A Government Is a Body of People, Usually Notably Ungoverned
  65. Re:Garbage by Gravis+Zero · · Score: 1

    I don't think anyone would be too happy using a kernel of an OS that relies on garbage collection. seems like a lot of pray and hope it works.

    --
    Anons need not reply. Questions end with a question mark.
  66. Re:Garbage by Dan+Farina · · Score: 1

    I much prefer the current model...where one just prays and hopes it works.

  67. Re:RAII is a bad reason for manual memory manageme by GileadGreene · · Score: 1
    For those myriad langauges for which it is not a part, are we supposed to do all the extra work of implementing it?

    If those languages are garbage collected, and you want some kind of RAII-style resource management, then yes, I suppose so - RAIInit won't work. Otherwise, by all means use RAIInit. My original point stands: RAIInit is not a good argument for abandoning GC.

    So where's the big push for file handle collection?

    Performing "file handle collection" (or "lock collection") would leave you in the same boat that attempting to use finalizers for closing files in a GC language would land you: files (or locks) would not be guaranteed to be closed (or released) at a predictable time. For the majority of applications it isn't necessary to have completely predictable object destruction (which is why GC can be used), but predictable file and lock release is a necessity.

  68. Re:RAII is a bad reason for manual memory manageme by Arandir · · Score: 1

    My original point stands: RAIInit is not a good argument for abandoning GC.

    Ummm, that wasn't your original point. You may have meant it to be, but it wasn't. Besides, you can't abandon GC if you've never adopted it...

    For the majority of applications it isn't necessary to have completely predictable object destruction (which is why GC can be used), but predictable file and lock release is a necessity

    Sometimes predictable object destruction IS necessary. But if your language doesn't support it because it considers memory to be a second class resource taking a hind seat to files and locks, then you're screwed.

    One size does not fit all. That's all I'm saying. Right now as I type I should instead be finishing coding on this hardware device driver I'm getting paid to write. I'm trying to wrack my brains figuring out how total control over memory allocation and deallocation isn't necessary for this project, and I can't figure it out. The problem is not that I'm an exception to the rule, the problem is that you're trying to fit a rule to everyone.

    --
    A Government Is a Body of People, Usually Notably Ungoverned
  69. Re:RAII is a bad reason for manual memory manageme by Valdrax · · Score: 1

    Malloc a huge chunk of memory. Custom cut one or more items out of the huge chunk, manually managing byte alignment of the objects to ensure portability between different chipset architectures. This is what most people refer to as a "custom allocator" (possibly also a pool or slab allocator) and its performance is vastly higher than an equal number of new's in a GC language.

    What about that scheme can't be done in a GC language when needed in critical sections and abandoned when not? Sure it's ugly to do in those languages, but so's writing your own GC in a non-GC language (e.g. SmartPointers).

    Incidentally, this is the sort of thing that your OS should be doing for you. No one pratically needs this level of control unless they're flying without a well-featured OS (i.e. working in an embedded context). People pulling this sort of nonsense in a normal application are just setting themselves up for a fall.

    Just don't complain when you're shopping around for a product and find one that is 5x the speed of its GD'd competitors. Then you the customer are forced to pay the price for programmer laziness and/or convenience.

    Just don't complain when you're shopping around for a product and find one that has 5x the number of crashes and exploits of its GD'd competitors. Then you the customer are forced to pay the price for programmer obession with trying to optimize non-critical sections.

    --
    If it's for-profit but free, you're not the customer -- you're the product (e.g., the Slashdot Beta's "audience").
  70. Re:RAII is a bad reason for manual memory manageme by dkf · · Score: 1
    Sometimes predictable object destruction IS necessary.
    For what? The reason why GC can get away without it is that you can have many tens or hundreds of millions of objects with modern physical memory sizes. By contrast, even if I recompile the kernel I'm not going to be able to sensibly handle even close to that many file descriptors.
    --
    "Little does he know, but there is no 'I' in 'Idiot'!"
  71. Re:RAII is a bad reason for manual memory manageme by GileadGreene · · Score: 1
    Ummm, that wasn't your original point. You may have meant it to be, but it wasn't.

    The original subject line: RAII is a bad reason for manual memory management (it's still the subject line now). Is manual memory management always a bad idea? No. Nor did I ever claim that it is a bad idea. What I said was that a desire to use the RAIInit idiom is not a good justification for manual memory management (specifically, because there are alternative idioms that work just as well in GC languages). I also asked for some other (i.e. non RAIInit-based) justification for manual memory management. Predictable object destruction is a perfectly good reason for manual memory management, and I'm certainly aware that there are applications that may require it. But that isn't the reason the original article gave.

    Besides, you can't abandon GC if you've never adopted it...

    Which would explain why I said

    If those languages are garbage collected, and you want some kind of RAII-style resource management, then yes, I suppose so - RAIInit won't work. Otherwise, by all means use RAIInit.
    The second sentence is about languages that are not GC (and thus would not need to abandon GC).

    Frankly, I'm a little confused about what you're trying to argue about here. You started by asking wanting/needing the initialization idiom, moved to the need for constructors, and eventually ended up at manual memory management being necessary for some tasks (because of reasons other than a need for RAIInit). So, what exactly are you trying to say that contradicts my original (and continuing) point, that "RAII is a bad reason for manual memory management"?

  72. Re:RAII is a bad reason for manual memory manageme by GebsBeard · · Score: 1
    What about that scheme can't be done in a GC language when needed in critical sections and abandoned when not? Sure it's ugly to do in those languages, but so's writing your own GC in a non-GC language (e.g. SmartPointers).

    Never seen it done in any language other than C or C++. Perhaps it is possible in C# but you'd have to be in unsafe mode the whole time. I'd love to hear how its done. I've had the good fortune of building an incremental GC system in C integrated into a memory manager and it was tricky to get right but with time it became rock solid, so it can be done.

    Incidentally, this is the sort of thing that your OS should be doing for you. No one pratically needs this level of control unless they're flying without a well-featured OS (i.e. working in an embedded context).

    There are things the OS can do and there are things it can't. It would be nice for the OS to provide all relevent services but sometimes they just aren't there and other times for the sake of portability you have to manage it at the application level. This is more true for enterprise-class software than one-off hacks.

    People pulling this sort of nonsense in a normal application are just setting themselves up for a fall.

    I will agree that this is an arena for experts. Inexperienced or incompetent people will hang themselves when they wade in this deep. Look its all just memory anyways. What you do with it is up to you. If you consider C as a "high level assembly language" (which it is) then this kind of "nonsense" is par for the course and even expected. Would you rail against an assembly language programmer for doing this?? Don't fault the language for allowing it (or the expert for doing it) simply because it looks like your idea of a high level language.

    Just don't complain when you're shopping around for a product and find one that has 5x the number of crashes and exploits of its GD'd competitors. Then you the customer are forced to pay the price for programmer obession with trying to optimize non-critical sections.

    I disagree. You are describing a product with poor QA testing, not a defect inherent in manually managed memory. If you dislike unstable products blame the company foisting this piece of shite on the market. Its not a huge stretch to say software that is tested thoroughly tends to become more stable regardless of its memory management scheme. And I would hardly call memory alloc/free optimization non-critical. It is the single biggest (non-algorithm based) drain on processor time, beyond even synchronization.

  73. You're confusing different concepts. by cakoose · · Score: 1
    ... predictable memory management can be used for controlling access to files and similar resources, creating safer thread locking code and even providing better error messages.

    You're listing things that can be made easier with the C++ RAII idiom. This has nothing to do with garbage collection. C#'s "using (...) { ... }" construct does what you're asking for. The only difference is that the scope is more explicit (which was a conscious design decision, not a constraint imposed by garbage collection).

  74. 80-20 rule by gtm256 · · Score: 1

    There's a rule that 80 % of the cpu time is spent in 20% of the code. http://en.wikipedia.org/wiki/Pareto_principle So why not use both GC and non-GC languages together? Write the app first in a user friendly language like Python and then optimize the slow parts in C++. Then you can focus on your design and less on your heap.

  75. GC vs. non-GC by Vorlath · · Score: 1

    The difference between the two is that if you give a non-GC tool to a beginner, it will blow up in his face and make it clear that the person needs more practice and experience in programming. Now give a GC tool to a beginner and he will think he is a professional. Only much later will the program callapse under its own weight, but to the beginner, it worked for a while and can you really pin the bug on him? This discussion is void. If you're arguing FOR GC, you're a beginner, plain and simple. Advanced programmers use it when appopriate and not when it's disavantageous. Languages like Java that force you to use GC and where you can't tell the GC that an object should be deleted is not a real language. When I program, I don't like having chains around my ankles. This is not bias. Java is a subset of C++ and always will be. It's just a fact and if you use Java, then you must be aware of its limitations is all.

    1. Re:GC vs. non-GC by shobadobs · · Score: 1

      Languages like Java that force you to use GC and where you can't tell the GC that an object should be deleted is not a real language.

      It is obvious from reading this that you're not an "advanced" programmer.

    2. Re:GC vs. non-GC by Vorlath · · Score: 1

      Setting a pointer (otherwise known as a reference in Java) to nil is prone to errors and doesn't guarentee deletion. That's my main point. I'd rather tell the system that I'm done with that memory and be nice to other applications that are also running. That's not advanced programming, it's common sense. And in Java, if you can't even do regular programming, how are you supposed to do anything "advanced"? I'm not bashing Java. It is what it is.

    3. Re:GC vs. non-GC by Anonymous Coward · · Score: 0

      For what it is worth I completely agree with you wrt running alongside other applications. If Java/.NET/etc would allow me to simply dispose of an object when I know I'm finished with it and immediately reclaim the memory/resources associated with that object I'd drop all complaints I have about GC in general.

  76. Real Garbage Collection by MemoryAid · · Score: 1
    Pros:

    Keeps house and yard cleaner
    More efficient bulk processing of waste
    leaves room for technoligical advancements in disposal methods

    Cons:

    Encourages people to discard more stuff
    Reduces public awareness of waste and pollution issues
    Some garbage trucks are bad polluters

    You see, I don't know what the rest of you are talking about, but I do want to contribute.

    --
    Language students: Don't try to learn English here. This ain't it.
  77. Re: memory management in games by SEAL · · Score: 1

    In most cases, the total run-time cost of garbage collection is lower than that of malloc/free memory management, at the cost of higher on-average memory usage (which can obviously destroy performance if you end up having to swap). On the other hand, application-tuned manual memory management using pooled allocation is generally faster than GC. Whether or not pooled allocation increases memory usage as much or more than GC depends on many things. Another consideration is that although GC often consumes less total CPU cycles than malloc/free, non-incremental collectors tend to use those cycles in big batches, which can produce GC 'pauses'. That's bad for some applications. Incremental collectors can minimize this effect, but only with some cost in CPU cycles.

    At the company I used to work for, we handled our own memory management (to the point of overriding new and delete, and creating our own memory pool for certain tasks).

    The three main problems this addresses in a game are: memory fragmentation, control of the AMOUNT of memory usage, and control of the TIMING of de/allocation.

    In a game, especially a PS/2 game, memory is a premium. You want to keep the code as streamlined as possible so you have enough memory to load levels that are a reasonable size.

    Memory allocation is a CPU hit as well, especially deletion, as many others mentioned already. A GC usually cannot be relied upon to cleanup at opportune times in a game. For example, I might want to free objects when the player is in a menu but never when he's in combat.

    But am I against GC in general? Hell no. It is very helpful in avoiding programmer error and making applications more secure. It also provides a better C++ environment. Ever try writing code that uses exceptions w/o a GC, and you'll soon be pulling your hair out.

    Anyhow just my $.02

    SEAL

  78. Re: memory management in games by swillden · · Score: 1

    Good points, just one quibble:

    A GC usually cannot be relied upon to cleanup at opportune times in a game.

    That isn't necessarily true. It depends on your choice of GC implementation, and the way that you use it.

    --
    Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.
  79. Re:RAII is a bad reason for manual memory manageme by Anonymous Coward · · Score: 0

    Look up the FFI sections on languages like haskell, a few common lisp implementations, etc, and use your imagination. Opaque data within FFI objects isn't subject to collection in most such systems.

    Orbitz is a concrete system that uses this technique in its backend. The backend is primarily common lisp, with some data structures that aren't well suited for lisp land being accessed by FFI.
    The data structure clients include access paths where "do this quickly" is important.

  80. Re:Garbage by Kosgrove · · Score: 1

    OS kernels are entirely too performance-critical to use garbage collection anyway.

  81. Re:Garbage by Gravis+Zero · · Score: 1

    hexactly. however, SUN thinks differently.

    --
    Anons need not reply. Questions end with a question mark.