Live data from Hacker News

Garbage Collection is Wrong

lb-stuff.com

101–110 of 111 posts

Re: Garbage Collection is Wrong

#101
post #76
post #62

Earlier quoted context omitted.

Isn't that equivalent to using a shared_ptr directly, just unnecessarily complicated? Reference counting works fine as long as you don't have cycles, of course.

The solution above works even if your graph has cycles. Of course if you know that it doesn't you can just build the graph with unique_ptrs.

It works with cycles, as long as you can know exactly when you want to remove something from the graph (as opposed to having it be removed when no longer referenced). Reference counting works fine that way too, though. It's a bit more work, but you just dive into the structure and manually remove references which breaks any cycles it may be involved in.

Re: Garbage Collection is Wrong

#102
post #79
post #66

Earlier quoted context omitted.

You asked for a situation where the lifetime of a resource can't be directly tied to the lifetime of a single storage location. Cycles are a different matter.

>You asked for a situation where the lifetime of a resource can't be directly tied to the lifetime of a single storage location. I don't think I asked for that but correct me if I did (maybe I'm just not understanding your point). Anyways, could you elaborate why shared_ptr, unique_ptr, and weak_ptr don't work in that case?

Oops, wasn't you, but the OP I was responding to initially.

shared_ptr works fine for my example. Shared immutable state is a case where reference counting works extremely well, since immutability implies no cycles.

Re: Garbage Collection is Wrong

#103
post #64

Earlier quoted context omitted.

> The vast majority of resources are short-lived and don't create cycles. Our garbage collections "systems" should be designed for this case. Many modern GC systems are tuned for exactly this. It often is called generational garbage collection and the youngest generation is tuned to quickly collect these short-lived and non cyclic objects. I used to work in this field so I've got at least a decent grasp of what moder…

My point is that, what GCs do at runtime (discover garbage) can be done statically in all of these cases. The sole reasons GCs do that work at runtime is because of cycles. Cycles aren't common at all and the answer shouldn't be "let's create a huge complex GC that handles all cases, then down the road we'll optimize for the common case" the answer should be "let's do the sane reasonable thing that handles the common…

Someone mentioned returning a closure from a function. That's something that is done all the time in higher-level languages and hard to do without a GC.

Also, in general GC's are much faster than reference counting (especially when the reference count updates needs to be thread-safe), so the only reason one would use them is to have deterministic object destructions. These aren't common at all and should not be the deciding factor when choosing a memory management scheme.

Re: Garbage Collection is Wrong

#104
post #26
post #23

Earlier quoted context omitted.

RAII is great, and should be used where appropriate. I'm not sure what it has to do with reference counting, though. Reference counting is just a particularly slow and unreliable form of garbage collection; I don't see why you would ever prefer it to a proper garbage collector.

Classic RAII in C++ is a limited form of ref-counting (only one ref). I have to disagree with your second statement, ref-counting is extremely fast. If you consider it a GC then it's the fastest GC. It's also deterministic and does not pause.

Two extra memory accesses plus whatever overhead for you have for locking if you are multi-threaded? That's pretty much the opposite of fast.

With refcounting you have:

  - Slow memory allocations (need to manage a fragmented heap)
  - Slow accesses and pointer handovers (updates to the refcounter)
  - Slow free (need to manage the free list)
  - No asynchronous pauses (since there is no garbage collector)
With a GC, you get:

  - Fast allocations (usually just an "add" instruction since the heap is not fragmented)
  - Zero cost accesses and pointer handovers
  - Zero cost free (just stop using the pointer)
  - Some asynchronous pauses and CPU usage while running the GC
It turns out that the cost of the first three points when using refcounting are much higher than that of the GC. Another reply to your post included references to actual research on this subject.

Re: Garbage Collection is Wrong

#105
post #96
post #50

Earlier quoted context omitted.

You can run out of space on the stack, which has a smaller size than the heap, where new'd objects are placed. This can easily happen with large objects that own other large objects and it is difficult to debug without knowledge of the implementation of all of the child objects.

That's too strong of a critique. You can have just a handle on the stack, with the data on the heap. When the destructor of the handle is executed, it deallocates the data on the heap. This is what almost all resource holding library or user-defined types do in C++.

Sure, but at that point, it's not RAII all the way down. RAII is a great wrapper around new and delete, but I saw people talking about how they rarely use new and delete anymore.

Edit: Actually, reading about auto_ptr and friends I see what you're getting at. The codebase I worked on some years ago didn't use those so I'm not totally familiar with that idiom for wrapping heap allocation.

Re: Garbage Collection is Wrong

#106
post #90

Earlier quoted context omitted.

Well, reference counting is definitely a way to collect garbage, but when people say X language used a reference counting GC versus a collecting GC, they typically mean that X language was using that GC for all objects. I'm guessing that the .NET experiment you're thinking of used the terminology in that way, and if so, I don't think it's particularly surprising that reference counting was slower. But using a referen…

Of course, you are right, I did not want to imply that we should call C++ a garbage collecting language just because it has shared_ptr. And you are right that you can achieve more optimal code if you can use you knowledge to decide when reference counting is necessary and when not. But there is just an enormous spectrum of cases where the convenience of a garbage collector - which gives you less (but not zero) opport…

> But there is just an enormous spectrum of cases where the convenience of a garbage collector - which gives you less (but not zero) opportunities for memory leaks and speeds up development

I think the article is actually more of an argument against that line of reasoning than an argument about performance. Its main proposition is that properly used RAII gives you less opportunities for resource leaks of all sorts, and is very easy to do. I agree with you that it isn't wrong in all scenarios (I mostly program in Ruby and Javascript for goodness sake!), but I think a lot of people are unaware of some of the advances in patterns, libraries, and compilers that make it much easier to write software that doesn't need a GC.

Re: Garbage Collection is Wrong

#108
post #89

Earlier quoted context omitted.

Professional C++ coder here. Seeing new and delete has very heavy code smell and can be avoided 99% of the time.

What have you done to your language that the native syntax for creating and deleting objects is a code smell?!

They are the primitive functions for making and destroying objects on the heap which requires more care than construction and destruction on the stack.

Re: Garbage Collection is Wrong

#110
post #63
post #47

Earlier quoted context omitted.

Say you are implementing a self-tracking objects model for data management. How do you fix the reversal of control required to manage that? Specifically you need to go from the representative object to the controller to store the fact that you changed.

Could you elaborate?

Entity Framework, when you modify an object it stores in a central location what the change was to be written out to a location latter.

It is performance wise infeasible to avoid that circular reference because it is very easy to pull back a lot of data from entity framework and change none of it.

Post reply on HN