When NOT to use garbage collection?

2019-03-18 17:37发布

The obvious cases for not using garbage collection are hard realtime, severely limited memory, and wanting to do bit twiddling with pointers. Are there any other, less discussed, good reasons why someone would prefer manual memory management instead of GC?

11条回答
够拽才男人
2楼-- · 2019-03-18 18:22

Emm... my professor's reason is to make our (his students') life harder and to teach us "the real thing". Haha :)

In general, though, garbage collection is not always optimized for your specific app, so if you're one good programmer, you will definitely do a better job at memory management than GC ever will.

查看更多
唯我独甜
3楼-- · 2019-03-18 18:23

When programming for embedded devices with limited resources. iPhone, for instance, uses reference-counting.

Or when programming something that is extremely intensive on your computer. SETI@Home and video games come to mind.

I would advise that you don't manage your own memory unless the situation dictates it's really necessary. Somebody famous once said that code is twice as hard to debug as it is to write. Well, memory management is hard enough in the first place. :)

查看更多
Luminary・发光体
4楼-- · 2019-03-18 18:29

One possible answer is, "Where security / system stability is not a primary requirement".

Bear in mind that applications given free reign over memory can cause all sorts of security concerns, including that of simply allocating and not freeing memory (DoS attack by slowing system to a standstill through insufficient available memory resource). This is a core part of Java's security model, for instance -- its GC ensures this can never happen.

My view, like that of Jon Harrop, is that GC adds overheads to system performance for several reasons (noted in other answers here); it is more indirect but more secure and takes responsibility for memory management away from the application developer; but there is always a performance cost for satefy nets.

查看更多
Root(大扎)
5楼-- · 2019-03-18 18:33

It IS possible to use garbage collection with hard real time, if you have fully incremental garbage collector with bounded execution time per byte of allocated memory, so, crazily enough, it is NOT necessarily a reason not to use garbage collection :)

One fundamental problem with garbage collection, though, is that it is difficult to estimate and manage the actual size of the working set in memory, because garbage collector can free your memory only delayedly. So, yes, when memory is restricted, garbage collection might not be a good choice.

Another problem with garbage collection is that it sometimes interferes with freeing other resources such as file descriptors, window handles, etc., because, again, the garbage collector might free those resources only delayedly, causing resource starvation.

Garbage collection can also cause cache trashing, because the memory is not necessarily allocated in a local fashion. For example, stack allocated memory is much more cache-friendly than heap-allocated short-lived objects.

Finally, garbage collection of course consumes CPU time :) So if you can code manually memory management you can save the CPU cycles the garbage collector would consume :)

查看更多
Root(大扎)
6楼-- · 2019-03-18 18:34

Garbage Collection vs Leaks

One of the primary reasons for me to avoid garbage collection is to avoid resource leaks in areas where leaking is critically bad. Garbage collection is great when safety and simplicity is your goal, but not to avoid leaky software.

A common scenario we've encountered with GC is that it's hard to avoid resource leaks with it.

Now this might confuse some people and seem paradoxical as to how garbage collection combined with less-than-ideal team practices can lead to leaky software, but the non-trivial management of resources in a software lie not with resources tied to a limited scope, but the persistent ones that linger around.

Complex Resource Management

An example of such complexity is a scene graph in a 3D software with millions of lines of code and thousands of objects and classes interacting with each other through events.

In these cases, these persistent objects often store handles/references to resources in the system, perhaps other objects living in the persistent scene graph. In such scenarios, you can have a central resource, R, like a complex 3D model that takes hundreds of megabytes of RAM, being accessed by many different parts of the scene and the user interface. For example, both a camera and light object might store a list of references to objects to exclude from the camera view and lighting system, of which such complex 3D models could be included.

In these cases, and in a team environment, it is not too uncommon for 3 separate developers to write code that stores persistent handles/references to R in dozens of different places in code. When the user removes R, all of these places should release the handle/reference.

Without garbage collection, if one of them fail to do so (perhaps he/she was having a bad day, is one of the less experienced developers, was in a high-pressure deadline crunch with looser testing and review standards, whatever the reason), a dangling pointer/handle/reference is left. Accessing it will crash the application with a segfault. Tracing such a segfault with a debugger will often immediately reveal where and why it happened.

With garbage collection, nothing obvious may happen except that running the software for longer periods of time continue to leak more and more resources. Because one of these places forgot to release the reference, permanently extending its lifetime, and continue using it in a valid, non-destroyed state, the software may not only continue to rise in memory usage but also get slower and slower the longer you run it processing hidden objects that are no longer visible to users.

To Crash or Not to Crash

In these types of cases, sometimes the obvious and glaring crash resulting from this mistake that can be immediately caught and handled during testing is actually preferable to a silent and very difficult-to-spot resource leak that could be a nightmare to trace down and may never be fixed.

So if you are working on such a project where an immediately obvious and correctable crash during testing might actually be preferable to a leaky software that often flies under the testing radar with such mistakes, garbage collection, unless it is combined with very careful coding standards and an awareness among every team member to watch out for its pitfalls (the need for weak or phantom references, e.g.), can actually do more harm than good. To me, garbage collection works best with much smaller, tighter teams and projects with actually a higher, not lower level of expertise in state/resource management, or ones where such resource leaks aren't anywhere near as bad as crashing.

From an in-the-trenches developer perspective, a glaring, in-your-face, showstopping bug is often preferable to the very subtle, hidden, 'no one knows what happened but something bad happened' kind of bugs. It often spells the difference between your debugger telling you what happened versus blindly flailing about trying to find needles in a haystack of millions of lines of code. Managing resources in large-scale systems is one of the most difficult things to get right, and garbage collection doesn't actually make this any easier. To crash or not to crash, that is the question, and in these scenarios we're often looking at the dangling handle crash without GC or the mysterious resource leak with it. In performance-critical applications dealing with potentially enormous resources, such leaks are often unacceptable.

查看更多
登录 后发表回答