• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Jeanne Boyarsky
  • Ron McLeod
Sheriffs:
  • Paul Clapham
  • Liutauras Vilda
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
Bartenders:

why the finalize is not calld?

 
Ranch Hand
Posts: 160
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hey guys,
class A
{
int a;
public void finalize()
{
System.out.println("garbage collected");
}

}


class Main
{
public static void main(String[] args)
{
System.out.println("hi");
A obj1=new A();
System.gc();
}
}

in this code, i was expecting the finalize method to be called and the message "garbage collected" to be printed when system.gc() was called...but its not happening..please tell me what im missin.
 
Bartender
Posts: 1464
32
Netbeans IDE C++ Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Thejwal.

At the time you call System.gc, your obj1 object still exists. It will continue to exist until it goes out of scope, which won't happen until the main() method of your Main class exits. Nothing for the garbage collector to collect (as far as obj1 is concerned) at the time you call it.

I suppose an optimization might detect that no references are made to obj1 subsequent to your System.gc() call, and assume it is safe to garbage-collect at that time, but there's no way to rely on that (that is, even if an optimizer did dispose of obj1 on its own, you can't be sure of when it might do that).

Try adding before your System.gc() call and see if that forces a call to finalize(). Remember, though, that the garbage collector can run without you calling System.gc(), so even if you see "garbage collected" on your console, you can't be sure if that resulted from your System.gc() call, or if it resulted from the garbage collector being run for some other reason.
 
Ranch Hand
Posts: 133
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You have no control over running the GC in java. It is completely decided by the JVM. By invoking System.gc you are simply requesting the JVM to run garbage collector which will effectively be JVM's decision.
 
sinatra roger
Ranch Hand
Posts: 160
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
yeah assigning null invokes finalize as pointed out by by steve..
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

thejwal pavithran wrote:in this code, i was expecting the finalize method to be called and the message "garbage collected" to be printed when system.gc() was called...but its not happening..please tell me what im missin.


And further to what Stevens said: You cannot tell Java to garbage-collect, you can only ask. Chances are it will; but it's NOT guaranteed (especially when you've only created one object). Garbage-collection is expensive, so the JVM is perfectly entitled to refuse (or defer) your request if it wants.

Which is one of the reasons why you almost never want to use finalize().

Winston
 
lowercase baba
Posts: 13091
67
Chrome Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you create one tiny object, and then set all references to null, you probably still have a ton of free memory. So even if you ask the gc() to run, I would think any intelligently designed process would say "I sill have 99% of my available memory free...I'm not going to waste time doing a gc right now", and would not do anything.

And if the JVM is exiting, all the memory is going to be freed up anyway, so again, there is no reason to run the gc.

My understanding (and I am by no means an expert) is that is is VERY hard to reliably get the gc to run when you want it to do so...I wouldn't ever count on it at all...
 
Stevens Miller
Bartender
Posts: 1464
32
Netbeans IDE C++ Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
And further to what Winston said, if you know where you want to call finalize(), you can simply replace it with some other method and call that explicitly instead. Indeed, that's the only way to know for sure that such a method is called, as System.gc() only suggests that garbage collection take place (well, the API doc says the JVM will make its "best effort" to collect garbage before the gc() method returns, but only the folks at Oracle know what "best effort" really means).

FWIW, here is what "Murach's Jave SE 6" has to say about finalize():

Although you can code for a more specific finalize method for an object, that's generally not a good idea. Since you can't tell when the garbage collector will call this method, you can't be assured that your finalize method will be executed before the program terminates. Therefore, you shouldn't rely on the finalize method to handle any timely tasks.



Java lacks destructors, on the theory that a managed language doesn't need them. finalize() might exist to handle cases where system calls allocate resources unknown to the JVM. (For example, if you allocate a paintbrush in Windows), giving you a sort of last-chance way to be sure you clean up after yourself. But, again, if you know you have to do it, you should code for it explicitly, rather than try to catch it in a place where you can't control when (or even if) it runs. (And, before anyone pounces on me, finalize() is not the same as a destructor.)

Of course, I sense you may have tried this for the sake of learning something. Nothing wrong with that! In fact, I hadn't read Murach's page on this before just now, so I'm glad you asked.
 
Marshal
Posts: 80230
424
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

thejwal pavithran wrote:yeah assigning null invokes finalize as pointed out by by steve..

No, it doesn’t. Nor does a System.gc() call, which is a sort of suggestion. The only thing which invokes finalize() is the JVM.
 
Yogesh Gnanapraksam
Ranch Hand
Posts: 133
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I became a little curious and tested this out in the following ways..

Test 1:


Output : hi


Test 2 :



Output : hi

Test 3:



output :

hi
garbage collected


This is where I am surprised. Call to Sytem.gc() makes the JVM run finalize!!

I commented only the line 'obj1 = null " only and then tried again..

Test 4 :


output : hi

Now finalize is not invoked.
 
author
Posts: 23958
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Yogesh Gnanapraksam wrote:I became a little curious and tested this out in the following ways..

Test 1:


Output : hi




I commented only the line 'obj1 = null " only and then tried again..

Test 4 :


output : hi

Now finalize is not invoked.



The garbage collector only finalizes an object prior to collecting it. In both of these cases, the objects are reachable, and hence, not eligible for garbage collection.

Henry
 
Henry Wong
author
Posts: 23958
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Yogesh Gnanapraksam wrote:

Test 3:



output :

hi
garbage collected


This is where I am surprised. Call to Sytem.gc() makes the JVM run finalize!!



Why is this surprising???

Henry
 
Yogesh Gnanapraksam
Ranch Hand
Posts: 133
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Why is this surprising???



Why is this not happening in Test 2 ?
 
Henry Wong
author
Posts: 23958
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Yogesh Gnanapraksam wrote:

Why is this surprising???



Why is this not happening in Test 2 ?



In test 2, the JVM exited before the garbage collector ran. It is not mandatory for the GC to run prior to exiting.

Henry
 
Yogesh Gnanapraksam
Ranch Hand
Posts: 133
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
System.gc() just makes a suggestion to run the GC and it is upto the JVM to decide to run it or not. From the above code runs ,it seems that JVM runs the GC (provided the object is not reachable) when System.gc() is invoked. It does not exit without running the GC. In this case too JVM might have exited as well without running the GC but it complied with the request.
 
Henry Wong
author
Posts: 23958
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
First, let's take this off of the table, as it is bothering me....

Yogesh Gnanapraksam wrote:System.gc() just makes a suggestion to run the GC and it is upto the JVM to decide to run it or not..




Yes, it is documented that the gc() method is not guaranteed to trigger a Garbage Collection cycle. However, there are specific reasons for this, the JVM programers didn't just decide to randomly take it as a suggestion. The two most likely reasons are...

1. The JVM is configured to ignored programmatic gc requests, via a property value. The default is to *not* ignore those requests.... and I am guessing that in your case, you didn't configure it that way.

2. Another GC cycle may be in progress. This can be caused if you use a concurrent garbage collector, or maybe even one of those incremental collectors. Again, these collectors are not the default -- at least with the last (Sun/Oracle) JVM which I played with. Also the program is too small and too short lived to trigger a GC cycle based on memory usage.

So.... for this example, the "suggestion" argument probably doesn't apply here.

Henry
 
Henry Wong
author
Posts: 23958
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

For the rest ....

Yogesh Gnanapraksam wrote:System.gc() just makes a suggestion to run the GC and it is upto the JVM to decide to run it or not. From the above code runs ,it seems that JVM runs the GC (provided the object is not reachable) when System.gc() is invoked. It does not exit without running the GC. In this case too JVM might have exited as well without running the GC but it complied with the request.




I am acutally not sure what you are trying to say. Unless, your claim is that System.gc() always works, which from my last post, I agree.

Henry
 
Yogesh Gnanapraksam
Ranch Hand
Posts: 133
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

So.... for this example, the "suggestion" argument probably doesn't apply here.



Yes. I was trying to get to this point. Thank you.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Henry Wong wrote:the JVM exited before the garbage collector ran. It is not mandatory for the GC to run prior to exiting.


Yet another reason (which I didn't actually know; cheers Henry) for NOT using finalize().

@Yogesh: Is this simply research; or do you actually want to use finalize()? There are valid uses, but they are very few and far between. Java is NOT C++.

Wisnton
 
Stevens Miller
Bartender
Posts: 1464
32
Netbeans IDE C++ Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

thejwal pavithran wrote:yeah assigning null invokes finalize as pointed out by by steve..

No, it doesn’t. Nor does a System.gc() call, which is a sort of suggestion. The only thing which invokes finalize() is the JVM.


Yes, let me be clear: the GC will not call finalize() for obj1 if it isn't null when System.gc() is called, because obj1 still has an active reference. By setting it to null, you make it possible for its finalize() method to run when you call System.gc(), but by no means does this guarantee it will run, for all the reasons being stated in this thread.

Now, watch out, because the question of when (or if) garbage collection takes place has been known to provoke some very passionate arguments that many people describe as "religious" (meaning, I guess, that which side you are on is rather more a matter of what principles you most hold dear, rather than which are most compelling). As an example of how quickly this can become murkier than you might expect, have a look at the dispose() method of the Graphics class, and ask yourself why a managed language suggests you take responsibility for releasing an object's resources on your own.
 
Yogesh Gnanapraksam
Ranch Hand
Posts: 133
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Winston,
I am trying to get a better understanding with help from experts.I will put them into practice/educate my co-workers with these findings.
Regards
Yogesh
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Yogesh Gnanapraksam wrote:I am trying to get a better understanding with help from experts.I will put them into practice/educate my co-workers with these findings.


OK. Well, can I suggest that you might use your time better on other matters then?

finalize() is NOT guaranteed to run at all, and it is certainly not guaranteed to run in a timely fashion; so anything you might have assumed about it is probably not true.

My advice: Don't use it (and certainly don't rely on it) and move on to something more productive.

Winston
 
Stevens Miller
Bartender
Posts: 1464
32
Netbeans IDE C++ Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Understanding the GC is a good thing to pursue for a new Java programmer. You asked a good question, Thejwal.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stevens Miller wrote:Understanding the GC is a good thing to pursue for a new Java programmer...


I disagree completely.

One of the major points about Java is that you don't have to understand that stuff.
Furthermore, the business of GC is complicated by the fact that it is:
(a) threaded
(b) prioritized
(c) arcane (and, in some cases, proprietary)
and so it should be.

I want to create a Java object.
In a memory-managed language like Java, the only thing that prevents me from doing it is that the JVM can't.
Do I care why? NO - unless I'm trying to cover up a piece of bad programming.

If there is a genuine need to increase, let's say, heap space, you prove it in testing and then hand it over to someone like me, who will check again that it really needs to be done (we sysadmins guard our memory closely).

And in 11 years of writing Java programs, I've never had to call on my sysadmin.

Winston
 
Sheriff
Posts: 28368
99
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:

Stevens Miller wrote:Understanding the GC is a good thing to pursue for a new Java programmer...


I disagree completely.



I agree with your disagreement. These forums seem to contain a lot of people obsessing over things which really don't make any difference.
 
Henry Wong
author
Posts: 23958
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:

Winston Gutkowski wrote:

Stevens Miller wrote:Understanding the GC is a good thing to pursue for a new Java programmer...


I disagree completely.



I agree with your disagreement. These forums seem to contain a lot of people obsessing over things which really don't make any difference.




Since this debate seems to be heavily one sided among the experienced ranchers, I'll throw in a jab for the counter argument -- it's the devil's advocate side of my personality. In my opinion, if you are interested in learning something, go ahead and do it. Yes, it may be low on the usefulness scale. There may be other technologies that are more important. But learning is supposed to be interesting and fun, so if you have an interest in learning something, then by all means, dive into it.

Henry
 
Stevens Miller
Bartender
Posts: 1464
32
Netbeans IDE C++ Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Henry Wong wrote:

Paul Clapham wrote:

Winston Gutkowski wrote:

Stevens Miller wrote:Understanding the GC is a good thing to pursue for a new Java programmer...


I disagree completely.



I agree with your disagreement. These forums seem to contain a lot of people obsessing over things which really don't make any difference.




Since this debate seems to be heavily one sided among the experienced ranchers, I'll throw in a jab for the counter argument -- it's the devil's advocate side of my personality. In my opinion, if you are interested in learning something, go ahead and do it. Yes, it may be low on the usefulness scale. There may be other technologies that are more important. But learning is supposed to be interesting and fun, so if you have an interest in learning something, then by all means, dive into it.

Henry



Precisely, Henry. The introductory literature on Java tends to mention the GC rather often, but usually in vague terms that would naturally leave a new programmer (particularly one who is used to memory-management issues such as those created by C++) unsure and curious about it. Telling a new Java programmer that he shouldn't be putting time into understanding the GC, at least at the level this thread has addressed it (and rather well, imho), is like telling a child not to ask questions about what the grown-ups are saying. Yes, in the end, you learn that you should pretty much always ignore the GC, and just let it do its thing. But knowing why that's the right policy is a reflection of a programmer who knows their craft.

I programmed in C for over 20 years before learning Java. I imagine that's an entry path for a lot of new Java programmers (the C part, not necessarily the two decades). Understanding that the GC exists, that it cannot be forced to run despite the existence of the System.gc() call, that it may run at odd (and, sometimes, inconvenient) times, that it may require you to use things like the Graphics dispose() call, that finalize() is a protected, overridable, method that is inherited by every single Java object but that you should pretty much never call nor override it (despite its rather lengthy description in the API docs, which make it sound like it's useful, yet nowhere say it may never actually do anything for you)... all of this is part of what it is to know why Java isn't C, and how to write a good Java program in Java, rather than trying to write a good C program in Java (if you get my drift). I would add that, like the GC, references to enlarging the heap are also present in the intro books on Java. Knowing what that is and--as Winston points out--why it's probably not the solution to the problem(s) a new Java programmer might think it is, is also part of a Java programmer's craft.

Forgive me for running off at the mouth (or the keyboard), but this is a beginner's forum, and our OP asked a perfectly reasonable question. When I got started in Java, I asked a lot of similar questions. I have a pretty thick skin (I'm a politician; we have those 8-) ), but people telling me I should be putting my time into other things when I'm in the process of exploring a new tool always rubbed me the wrong way. If our OP has been taking the good answers here to heart, he now knows a lot of what a competent Java programmer ought to know about the GC.

But how were we going to help him do that if he didn't ask us in the first place?
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stevens Miller wrote:Forgive me for running off at the mouth (or the keyboard), but this is a beginner's forum, and our OP asked a perfectly reasonable question. When I got started in Java, I asked a lot of similar questions. I have a pretty thick skin (I'm a politician; we have those 8-) ), but people telling me I should be putting my time into other things when I'm in the process of exploring a new tool always rubbed me the wrong way. If our OP has been taking the good answers here to heart, he now knows a lot of what a competent Java programmer ought to know about the GC.


Unfortunately, we have to deal with an awful lot of types of "beginner"; from the ones that are in their first weeks of Java classes at school, to 20-year veterans such as yourself who are trying to come to terms with the differences between Java and whatever other language(s) they've learned.

Your analogy of 'telling a child not to ask questions about what the grown-ups are saying' is nice, but there's also the business of warning someone against behaviour that may hurt them. You don't reason with a child about putting their hand on a hot stove, you simply tell them not to do it. And I'd say that none us are saying "don't ask the question", we're simply saying "don't ask it yet; it's a bad use of your time". In many cases, complex explanations about the GC, or why not to micro-optimize, or (my personal fave) why to avoid reflection, are a waste of our time because the poster simply doesn't have the requisite knowledge to understand...yet.

My stock reply is usually: "I want a Java object, I make one and use it; and I let the JVM worry about when to clean it up". Obviously, it's an oversimplification, but the idea is to get beginner's over the hump of obsessing about things that don't matter - and until you're writing fairly sophisticated programs, it almost never does.

Hopefully that explains my reasoning at least.

Winston
 
Time is mother nature's way of keeping everything from happening at once. And this is a tiny ad:
Smokeless wood heat with a rocket mass heater
https://woodheat.net
reply
    Bookmark Topic Watch Topic
  • New Topic