views:

268

answers:

6

I was wondering about the garbage collection that takes place in Java. Is it really able to handle all objects that aren't used and free up the most possible memory?

I also want to know how does the Java garbage collection compare to another language like lets say C#? And then, how does the automatic garbage collection measure up against manual collection from a language like C?

+1  A: 

The garbage collector is implementation defined. There are different types of GCs in existence; which one is used is not something programs have to worry about.

I can't say for C, but in C++ we actually very rarely use a full-blown garbage collector, because C++ programmers have techniques like RAII and reference counting smart pointers that help simplify memory management.

In silico
"Simplify" being a relative term ;)
Rulmeq
+5  A: 

Yes, thats the point of garbage collection.

There are many different forms of garbage collection. The simplest form, reference counting, is not able to handle certain type of garbage (circular references) without enhancements to the algorithm.

Java (the Sun JVM) uses a generational mark and sweep collector, though this is not standardized and different JVMs do use different collectors. I do not know the exact collector used by the .NET CLR.

Garbage collectors like reduce programmer overhead, and can make certain algorithms perform better. However, their memory footprint is generally larger than a tight manual allocation system.

The defacto reference on this topic is the book Garbage Collection, which is well written and comprehensive.

Yann Ramin
Thank you. Will have a look at the book that you suggested.
Pieter van Niekerk
+1  A: 

The garbage collector(GC) runs from time to time to find references of objects. Those without any reference are marked first and the finalize() method is invoked. Next time the objects are removed from memory. GC makes programs a bit slow. You can influence the GC behavior but there is no guarantee.

SidCool
Simplify?? I thought managed languages were more simplified than traditional languages that doesn't use GC. Managed languages keep all the intricacies of memory management under the hood making it easier for the developers.
nitroxn
You are right. Is there anything I missed in your statement?
SidCool
"GC makes programs a bit slow". Actually, it depents. There are even cases where GC can be *faster* than manual memory management. Usually it just makes no difference...
sleske
+4  A: 

Is it really able to handle all objects that aren't used

No, it can't. It can, however, collect all objects which cannot be used anymore, and it does that very well. The difference is subtle, see below.


Explanation

For example, say you have the following code:

class A {
    public static Date d = new Date(); // d will never be collected
}

And let's say you know that after a certain time d will never be accessed again. The runtime system doesn't have that information, though, and d will be kept alive indefinitely, while in C++ you could explicitly delete it.

Instead, the garbage collector collects all objects that are no longer accessible. For instance:

void f() {
    Date d = new Date();
    System.out.println(d.toString());
} // d is no longer accessible at this point

The garbage collector detects that there is no way the object that d references will ever be accessed again, as d is its only reference and it goes out of scope at the end of the method. Collecting non-accessible objects is an under-estimation of the "what objects can be collected" question, but it's safe because it guarantees no live object will ever be collected.

The difference is subtle and indeed, in most sane code, all the objects that you no longer use will be collected. That collection itself is complete, able to correctly identify and collect every non-accessible object, and that includes objects which are not accessible because all their references reside in other non-accessible objects.

Oak
+1 very nice explanation of the basic idea
sleske
+2  A: 

Garabage collectors seach for objects and checks if they are referenced by valid pointers. If not, they are completedly removed. This removes potential problems such as having live pointers references dead objects and thus getting stuck in memory doing nothing.

Using a language that requires you to allocate, free, and re-assign space yourself (such as C) can be very tricky to begin with as you need to be in complete control of allocating space for any object you need and de-allocating any object you are done with without forgetting about any unneeded objects sitting around somewhere using up space. Tricky as it may be, it does have the advantage of performance.

Garbage collectors tend to de-allocate space at a low-level which can hurt performance. For most applications though, the performance decrease wouldn't be a big and thus not noticable.

Chris
+1  A: 

For .NET, take a look at Garbage Collector Basics and Performance Hints There you will also find some performance hints.

For Java, look at Java theory and practice: Garbage collection and performance. There too you wil find some hints and "anti-hints", i.e. ways to make GC worse.

Daniel Rose