I've always been glad that C++ doesn't have a Garbage Collector (GC), because you have little control over when or how long they run. When you're dealing with video, games, or anything that needs to run in realtime, this is a bad thing. However, after writing an FTP server I now wish that C++ did have garbage collection. Here's why...
NOTE: I highly recommend watching the video, as it's easier to understand in video form
- The FTP server has an loop that calls callback functions when events occur
- If someone (we'll call him Joe), connects to the server, requests a file, but gets impatient and kills the connection. The connection object gets deleted, but a later event (the file is loaded and ready to be sent to Joe) could occur after deletion, causing a crash
- So, we try to fix it by deferring object delete until outside the tight event loop:
- This works, until an asynchronous file operation takes longer than usual, allowing the loop to be exited and reentered
What About Smart Pointers
- Smart pointers certainly help. Shared pointers keep track of how many pointers are using an object, and delete them once the count gets to 0
- However, things go wrong when you have pointer loops:
- You can have loops with multiple objects too
- To work around this, you need to carefully insert weak pointers in to break the loops, and ensure a one way object ownership tree
- I've usually opted to use raw pointers instead, because:
- There's lock/unlock overhead with weak pointers, and that can be a problem in performance critical code
- The code is cleaner (no lock objects required, and no checking whether the object still exists)
- However, I did this entirely out of habit. I never tested whether the lock/unlock overhead was significant enough to require optimization
- Up till now I've gotten away with it, because the object ownership and destruction order has always been clear
- This time, I've paid for optimizing prematurely. My mistake...
How A Garbage Collector Would Help
- With a GC, I could simply delete references to an object, and the garbage collector would take care of the rest
- GCs can handle pointer loops, so no weak-pointers and locking/unlocking needed
- The GC would eliminate the crashing without me needing to manage object lifetimes and destruction ordering manually. It's taken care of automatically
Some have said that GC has had the biggest impact on programmer productivity in years, and is why developers using languages that come with GC are more productive. They don't write code faster; they simply don't need to manually handle memory management (although they should still think carefully about how their data is structured).
Now that I've written software that would benefit from an automated garbage collection, I definitely wish that C++ had GC. But, it should be optional and preferably come with more control over when it's run, and for how long.