1
votes

I was reading about Garbage Collection and finalize() method of Java and there are some of the doubts that caught my mind. Sorry if you think that these doubts are really silly.

  1. I was reading the article http://javarevisited.blogspot.com/2011/04/garbage-collection-in-java.html. In this, point 5 says: 'Before removing an object from memory Garbage collection thread invokes finalize() method of that object and gives an opportunity to perform any sort of cleanup required'. So does this thing happens for sure? I mean will the finalize() method be always called before execution of Garbage Collector method?

  2. How does the Garbage Collector knows that it needs to execute? For example, I have an application deployed on server, so when does the GC executes? Does it executes periodically, or when some (say 1MB) amount of garbage is collected and a trigger is executed or something or it is just random and there's no way to determine when will it execute?

  3. How does it degrade the performance of my application since the garbage collection isn't happening?

  4. Suppose I have a lots of garbage in my heap but the garbage collector isn't executed. If this happens, so isn't it a bad behavior or a flaw of JVM?

  5. Can we say that garbage collection which is done manually in C/C++ better than in Java taking the consideration that we as a programmer are smart enough and know when we need to dispose off the 'not-so-referenced' pointers?

3
Unfortunately, finalize does not happen "for sure". There are several bugs in the way it was originally designed, making it fairly unreliable.Hot Licks
In general, the GC does a sufficiently good job, and you should never need to write finalizers at all; there is one exception: if you use native resources which you need to free. The GC cannot care about them since it doesn't know about them.fge
The system does not get slower as "garbage" accumulates. True, the garbage occupies space, but the same is true of the freed space in a C++ heap, after objects are freed. At most, a GC environment may require a slightly larger working set.Hot Licks
There is no such thing as "Manual Garbage Collection".fredoverflow
@FredOverflow - You wanna stop by our house some Wednesday evening?Hot Licks

3 Answers

1
votes
  1. The finalize() method will always be called before the object is garbage collected. There is no "garbage collector method".

  2. The garbage collector will run whenever it feels like it. As a programmer you can't control it. Technically you can, by making lots of garbage or by calling System.gc(), but you don't need to.

  3. The garbage collector will run whenever it needs to. As a programmer you shouldn't need to be concerned about garbage collection performance, but there are some command-line options to tweak the behaviour of the garbage collector.

  4. If you run out of memory and the garbage collector does not run, that's a JVM flaw. It will run, though. The garbage collector will run whenever it needs to and whenever it's efficient. If it's more efficient to let the heap fill up with garbage before collecting any, then it will do that.

  5. This is a very subjective question and there are good reasons behind both sides. Java's garbage collection reduces programming errors, but C and C++'s manual memory management provides more consistent performance and memory usage.

1
votes

[1] The finalize call is part of the garbage collection.

[2] The strategy and invocation of the garbage collector is a detail of the implementation. Hence no answer here.

[3,4] If you have a lot of tiny garbage, the collector might not perform garbage collection. This hower might waste memory (I consider it a memory leak), if the 'tiny' objects hold memory the collector is not aware of (An image might be represented by a tiny handle/pointer to native memory).

[5] The concept of C++ is very different (omitting C here). A destructor can perform at a determite point to release resources allocated (See: RAII).

1
votes
  1. finalize() is supposed to happen right before the object is cleaned up. The problem is - you don't know when it's gonna be (and if it will even ever happen). Don't count on finalize to clean up, just do the cleaning yourself before the object loses its scope. Also, notice that finalize() runs on a garbage collection cycle. This means that if you implement finalize your garbaged object will take 2 cycles to clean up which means a waste of memory that can be cleaned. And also more CPU that will be consumed to run finalize and you won't know when. If you have lots of objects that have finalize then they might run together during GC which might pause your entire application for a long period of time.

  2. There are different algorithms that you can tune to decide when the garbage collection happens. Also, it depends on the heap size you allocate to your JVM (along with other parameters such as old vs new generation sizes, survivor space size and so on...). If you're dealing with small apps -usually the default configuration will be enough for you. If you're writing large apps and need to consider performance over time, CPU time, and pause times (sometimes the GC pauses the entire app) - then you better read about the heap memory model and the different GC algorithms and parameters you can tune to control the GC to better suite your needs.

  3. Your application performance is affected by the GC cycles that happen (not GC cycles that don't happen). For example - if your heap is too small, you'll have frequent cycles. If your heap is too big you'll have less frequent cycles but each of them might take longer to execute. Again, that's all depend on the GC algorithms and tuning parameters you choose as well as the heap memory allocation (how many memory for young generation, how many for old generation, survivor-space ratio and so on...)

  4. I don't see a scenario in which you have a lot of garbage and there's no collection, unless there's still enough space for allocating new objects. When the space runs out, or about to run out (depending on the collection algorithm you chose and the heap size and other params) there will be a collection.

  5. Java garbage collector solves a painful problem that programmers had experienced in the non-managed languages such as C or C++. It has its advantages and disadvantages. When you need absolute control on your memory, you'll use C. When you want to write systems more easily, and you don't mind allocating some extra memory for the GC, and to share a bit of CPU time with the GC, then you can write faster (and also more robust - because there are less memory leaks and other nasty stuff) with java.