• 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
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

Garbage Collection!

 
Ranch Hand
Posts: 428
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
How Can I setup manual Garbage Collection? What is difference between GC method and runFinalization and Finalize. I need three of them OR either of them?
Plz let me know,
Angela
 
author
Posts: 3252
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Angela Jessi:
How Can I setup manual Garbage Collection? What is difference between GC method and runFinalization and Finalize. I need three of them OR either of them?


You can't set up manual GC. You can politely ask that the system run the GC (System.gc()), but there is no guarantee about what this will do. You would call this if you know you will need lots of memory soon, and want to avoid a garbage collection pause in your application.
System.runFinalization() is in a similar position -- it's a polite request rather than anything else. Before the memory allocated to objects can be freed, the GC needs to run these objects' finalize() methods. runFinalization() is a request to run finalize() on all objects that await finalization so their memory can be cleared. No guarantees again. You would call this if you suspect that some of your garbage-collectable objects are holding on to resources (e.g. network connections) which they will free up when finalized. This is an indication of bad practice more than anything else; normally, you should have closed external resources well before an object becomes eligible for garbage collection.
- Peter

[This message has been edited by Peter den Haan (edited March 13, 2001).]
 
Angela Jessi
Ranch Hand
Posts: 428
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Thanks Peter,
But I am still confused i mean when i implement some code to run System.gc(), do i need to run runFinalization or finalize method... Can You explain me by simple code example..
plz let me know
angela
 
"The Hood"
Posts: 8521
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Angela,
unless you have some unusual DRIVING reason for being overly concerned about this, you don't have to do anything. Unlike C, java handles most of the issues for you. With out doing anything.
You shouldn't EVER have to explicitly run finalize either. The gc() will call the finalize method for the classes that it is trying to clean up.
Perhaps you DO have one of the unusual cases. Can you explain the scenario that makes you think that you need to do this?
 
Angela Jessi
Ranch Hand
Posts: 428
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Cindy,
I read that JVM itself runs Garbage collection whenever memory leaks or memory is low.
In Our project, we want to run garbage collection manually at specific location i mean when some objects we have set to NULL.
So I want to use System.gc(). As you have explain nicely, my concept is clear that if i used System.gc(), this method will automatically call finalize method and rum Garbage collection! So I don't have to use finalize() method...May I right?
Plz let me know
Thanks,
Angela
 
Cindy Glass
"The Hood"
Posts: 8521
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Actually when you set the variables to null and release all of the references to the object the garbage collector should run WITHOUT you having to call it. Like magic .
 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Great explanations. just one more doubt. if gc does the garbage collection..ok on its own will .. and calls the finalize() method on all objects available for garbage collection (sounds more like our sweeper) then what is the runfinalization() for?? maybe this sounds a little basic after all the explanations but please do elaborate on this.
 
Ranch Hand
Posts: 162
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by srinivas mand:
what is the runfinalization() for??


runFinalization give some virtual control to application .. it basically provide a hint to the JVM that it can call finalize on the un finalized object. As Peter said finalize method "would call this if you suspect that some of your garbage-collectable objects are holding on to resources (e.g. network connections) which they will free up when finalized"
 
Ranch Hand
Posts: 1923
Scala Postgres Database Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Angela Jessi:

In Our project, we want to run garbage collection manually at specific location i mean when some objects we have set to NULL.


Hi Angela.
You cannot run the gc manually.
No, you can't.
There is a command, to run the gc, but it will not run the gc.
It's just there to confuse you.
A second thing is the idea of setting some object to null.
That's of no good either.
A object MAY be garbage collected when it runs out of scope - absolutly independent, whether it is set to null or not.
If it can not be referenced from somewhere, it MIGHT be gc-ed.
Setting it to null is waste of time.
Manually starting gc is source-code-pollution.
Think of this:

leaving foo rbt1 and rbt2 are out of scope and get sooner or later gc-ed.
You needn't call gc.
You needn't call rbt1=null;
You needn't call rbt2=null;

gc isn't meant to be called by you and your project .
Of course, it' s documentation looks, as if it was, but it isn't.
 
Stefan Wagner
Ranch Hand
Posts: 1923
Scala Postgres Database Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Cindy Glass:
Actually when you set the variables to null and release all of the references to the object the garbage collector should run WITHOUT you having to call it. Like magic .


No! I guess you're wrong!
Setting the variables to null shouldn't be of any interest to the garbage collector.
See my posting before.
 
Bartender
Posts: 1844
Eclipse IDE Ruby Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Actually, setting nulls can allow objects to become eligable for garbage collection. Lets look at Stefan's example, with a slight change for my purposes (and line numbers added):

First, since it is declared as a local variable instead of a class member, s does not start out as null; it starts out as uninitialized (different from null). If you tried to do s.length() before initializing it, you would get a "might not have been initialized" compile-time exception. If s were a class member, it would be automatically initialized to null, and then you would get a null pointer run-time exception.
Second, s is not an object; s is a reference to an object. This works just like C's pointers, except you can't do pointer arithmetic. Thus, s is not eligible for garbage collection; instead, the object "pointed to" (referenced) by s may or may not be elegible fo garbage collection.
Now, line by line:
line 12 - declare a reference to a String object. Name this reference "s". As noted before, "s" is uninitialized.
line 14 - declare an integer i. Set this value equal to 7. This has no bearings on anything; no objects have been created at this point.
line 17 - create a new String object and assign it the value of "Am I null?" Have the already declared reference "s" point to this object. This increments the number of references to this String by one (from 0 to 1).
Why I didn't just state: s = "Am I null?" will (hopefully) become clear in a moment -- it's a special case.
line 19 - instruct the reference "s" to point to nothing. This decrements the number of references to the String object (from 1 down to 0). Since there are now no references pointing to the object created in line 17, it is eligable for garbage collection.
line 21 - instruct the reference "s" to point to the "Here I go again...." String object. This object is a String literal, and as such lives in the String pool. There is always a refernce to this object, so it will never be gc'ed. Increase the number of references to this object from 1 to 2.
line 22 - the local reference s goes out of scope. reduce the number of referenced of the object that it references; the string in the string pool has its references decremented from 2 back down to 1. Since there is still a reference to it, it is not gc'ed.
[ July 28, 2003: Message edited by: Joel McNary ]
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
[Stefan]: You cannot run the gc manually. No, you can't. There is a command, to run the gc, but it will not run the gc.
It's just there to confuse you.

Methinks you overstate the case. You can't guarantee that calling System.gc() will actually free up memory, true, but in my experience it really does run the garbage collector, and if it's possible to free up any objects, they generally will get freed up. It's certainly not perfect, but pretty good. In some situations it may indeed be helpful.
However, it's worth noting that System.gc() can actually reduce the effectiveness of the "standard" garbage collection normally being done it the background. This is because many modern JVMs use generational garbage collection, which concentrates its efforts on "young" objects which have a higher-than-usual chance of being temporary, transient things that are eligible for GC shortly after creation. Once a young object has survived a few GC attempts, it's considered "old" and the JVM doesn't try to GC it nearly as often. The system actually works quite well for many cases. However when you call System.gc(), one effect is that any objects that were not completely eligible for GC at the time of System.gc(), are now considered "old" and will now be harder to GC in the future because the JVM won't check them as often. And thanks to subtleties of how finalization works, a lot of the stuff that you think should be eligible for GC, probably isn't, until other finalizers run - and if System.gc() is called before those finalizers are run, it has the effect of prematurely moving a lot of unfinalized objects into the "old" category, from which they will take a much longer time to be GC'ed.
So, the short version - System.gc() does generally run the garbage collector, but it often does so in a way that makes other GC less efficient. So use it with caution, and test your results to see if running System.gc() is really producing tangible benefits in the long run.
[ July 28, 2003: Message edited by: Jim Yingst ]
 
Stefan Wagner
Ranch Hand
Posts: 1923
Scala Postgres Database Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Joel McNary:


It was a bad Idea, to use String as example, because you needn't call 'new'.
>First, since it is declared as a local variable instead of a class member, s does not start out as null; it starts out as uninitialized (different from null). If you tried to do s.length() before initializing it, you would get a "might not have been initialized" compile-time exception. If s were a class member, it would be automatically initialized to null, and then you would get a null pointer run-time exception.

This you should explain.
What is the difference between initializing to null, and uninitialized?
Beside of compilerwarnings.
I thought, that

fo2 might be null, fo1 is definitly null. line 310 only makes it explicit.
Second, s is not an object; s is a reference to an object. This works just like C's pointers, except you can't do pointer arithmetic. Thus, s is not eligible for garbage collection; instead, the object "pointed to" (referenced) by s may or may not be elegible fo garbage collection.

f1 is an object, while f2 isn't?
That's new to me.
In Line 530, how can you distinguish f1 from f2? What is the diffence?

Both refer to same Object - which is f2, which is f1, having (f1 == f2) - so if f1 is an Object, f2 must be an Object.
Can you tell in Line 30 which is an Object, and which is a Reference to an Object?
I guess you can't.
It's only one Object, of course.
With two names.
> line 12 - declare a reference to a String object. Name this reference "s". As noted before, "s" is uninitialized.
Disagree.
A reference is a reference to something. 's' isn't referring anything in Line 12, therefor it is a type referring nothing.
I agree to: "'s' is unitialized".
's' is of type String, or a Stringobject.
> line 14 - declare an integer i. Set this value equal to 7. This has no bearings on anything; no objects have been created at this point.
> line 17 - create a new String object and assign it the value of "Am I null?" Have the already declared reference "s" point to this object. This increments the number of references to this String by one (from 0 to 1).
> Why I didn't just state: s = "Am I null?" will (hopefully) become clear in a moment -- it's a special case.
Yes - shame on me.
Immutability of underlying Objects in String, special Notation without 'new', literal constants and the pool of those make String a bad candidate for discussion.

> line 19 - instruct the reference "s" to point to nothing. This decrements the number of references to the String object (from 1 down to 0). Since there are now no references pointing to the object created in line 17, it is eligable for garbage collection.
The object, created in Line 17 is of type String, and it' s name is 's'. "Am I null?" is a literal constant, used to initialize this object with a value.
"Am I null?" wasn't of interest to me, but s, and s is null, but not ready for gc.
>line 21 - instruct the reference "s" to point to the "Here I go again...." String object. This object is a String literal, and as such lives in the String pool. There is always a refernce to this object, so it will never be gc'ed. Increase the number of references to this object from 1 to 2.
The string pool is an implementation detail and of no interest.
Mixing 'reference to the string pool' and ordinary references will make things confusing.
And why should there be a difference between those literals "Am I null?" and "Here I go again" ?
I thought
[CODE|
2100: s = "Here I go again....";
2170: s = new String ("Here I go again....");
[/CODE|
Is just two ways to say the same thing.
>line 22 - the local reference s goes out of scope. reduce the number of referenced of the object that it references; the string in the string pool has its references decremented from 2 back down to 1. Since there is still a reference to it, it is not gc'ed.
Some lines before, you told us, that Strings from the pool will nether be gc-ed.
So why count those references?
And I was interested in the Object 's'.
The whole Question is turning into the wrong direction.
Suppose following class:
[CODE|
8110:class Foo
8120:{
8130:Bar b1;
8140:Bar b2;
8150:
8160: public Foo ()
8170: {
8180:b1 = new Bar ();
8190:b2 = new Bar ();
8200:}
8250:public foo ()
8260:{
8270:b1.bar ();
8280:b2.bar ();
8290:}
8300:}
8310:
8320:class Gooz
8330:{
8340:void gooz ()
8350: {
8360: Foo f = new Foo ();
8362:f.foo ();
8364:f = null;
8368:f = new Foo ();
8370:f.foo ();
8380:}
8390:}
[/CODE|
If someone calls Gooz.gooz (), Object f is created in Line 8360, a Foo, which contains 2 Bars.
In Line 8364 it is set to null, but might not be gc-ed - it is needed in Line 8368 again.
In Line 8380 this Foo f runs out of scope, and might be gc-ed.
It cannot be referenced from anywhere.
Those Bars b1, b2 are ready for gc too.
 
Joel McNary
Bartender
Posts: 1844
Eclipse IDE Ruby Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
[B]
fo2 might be null, fo1 is definitly null. line 310 only makes it explicit.
[/B]
Agreed - we don't know what fo2 is pointing at. Like C pointers, it could be pointing either at memory address 0x0000000 or to some random point in memory. Of course, Java hides the memory locations from us, so all we know is that we have a reference to an object of type Foo. Until we explicitly initialize it, however, the compiler assumes that whatever might be on the other end of the reference (including null) is invalid. So, if we try to use it before initializing it, the compiler will let us know.
[B]

f1 is an object, while f2 isn't?
That's new to me.
In Line 530, how can you distinguish f1 from f2? What is the diffence?
[/B]
f1 and f2 are both references to Foo objects. While in general parlance we can refer to them as Objects themselves, that's not really what's going on. f1 "points" to a Foo object in the heap, and then f2 "points" to that same object. You can't really tell the difference between the references;
they will work the same. But they are both references, not an Object and a Reference.

line 12 - declare a reference to a String object. Name this reference "s". As noted before, "s" is uninitialized.
Disagree.
A reference is a reference to something. 's' isn't referring anything in Line 12, therefor it is a type referring nothing.
I agree to: "'s' is unitialized".
's' is of type String, or a Stringobject.

If you work with or know C/C++, do not let the '.' syntax fool you. In Java, we do not work directly with objects -- they never enter the stack. This is the same as stating in C/C++:

Here, s is not a String; it is a (uninitialized) pointer to a String. The same thing is true in Java, except that the syntax is slightly different--you don't need the '*', and you use '.' instead of '->' to access members of the class.

Yes - shame on me.
Immutability of underlying Objects in String, special Notation without 'new', literal constants and the pool of those make String a bad candidate for discussion.

I agree I'll skip the rest and go straint to the meat of the matter here:
[B]
Suppose following class:

If someone calls Gooz.gooz (), Object f is created in Line 8360, a Foo, which contains 2 Bars.
In Line 8364 it is set to null, but might not be gc-ed - it is needed in Line 8368 again.
In Line 8380 this Foo f runs out of scope, and might be gc-ed.
It cannot be referenced from anywhere.
Those Bars b1, b2 are ready for gc too.
[/B]
Remember, the reference is not the object. On line 8360, an Object is created which ontains two Bars. On line 8364, the reference to that object is lost; so the object may now be gc'ed. On line 8368, a new Object is created, and at 8380 the reference runs out of scope, so the second object is eligible to be gc-ed. When the garbage collector runs, it will have to collect 2 Foo objects (and 4 Bar objects).
Using C notation to illustrate the difference between Object and Pointer (reference):

Note 8361 which defines fobject; this is an actual Foo object; f is just a pointer to a Foo object. We create three Foo objects here: one in line 8360, one in line 8361, and one on line 8368. On line 8375, we set the pointer f to point to the object created in line 8361.
Java has no equivelent for lines 8361, 8363, and 8365. Since you don't work directly with objects but instead manipulate them through reference to those objects, you simnple can't do things like this in Java--it doesn't make syntactic sense.
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
One other point I haven't seen addressed (though I might've missed it):

No, there's no way this could throw a NullPointerException, regardless of whether s was null or not. The reference s is definitely there; it hasn't been garbage collectied or anything - it's a varable which may be assigned a value. In this case, it's being assigned the value of a reference to the "Am I null" object.
In general, the only ways you [i]ever get a NullPointerException are:
  • You put a dot '.' to the right of a reference varaible, and that variable turns out to be null. E.g.
    foo.bar()
    or
    foo.baz
    These throw NullPointerException if foo is null. If baz is an reference variable, maybe it's null, but that wouldn't possibly throw a NullPointerException, unless you put another '.' to the right of it, e.g.
    foo.baz.bat;
    This could throw NullPointerException if either foo or baz were null - but not bat.
  • You explicitly choose to throw a NullPointerException, e.g.

  • You call some other method (perhaps in code you did not write) which does one of these two things. In which case it's either documented in the API, or it's a bug.


  • [ July 29, 2003: Message edited by: Jim Yingst ]
     
    Stefan Wagner
    Ranch Hand
    Posts: 1923
    Scala Postgres Database Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Joel McNary:
    [B]
    fo2 might be null, fo1 is definitly null. line 310 only makes it explicit.
    [/B]
    Agreed - we don't know what fo2 is pointing at. Like C pointers, it could be pointing either at memory address 0x0000000 or to some random point in memory. Of course, Java hides the memory locations from us, so all we know is that we have a reference to an object of type Foo. Until we explicitly initialize it, however, the compiler assumes that whatever might be on the other end of the reference (including null) is invalid. So, if we try to use it before initializing it, the compiler will let us know.

    Mixing in Concepts of C is not very helpful.
    Especially the distinction between 'reference to an object' and 'object' doesn't seem to be common to me.

    [B]

    f1 is an object, while f2 isn't?
    That's new to me.
    In Line 530, how can you distinguish f1 from f2? What is the diffence?
    [/B]
    f1 and f2 are both references to Foo objects. While in general parlance we can refer to them as Objects themselves, that's not really what's going on. f1 "points" to a Foo object in the heap, and then f2 "points" to that same object. You can't really tell the difference between the references;
    they will work the same. But they are both references, not an Object and a Reference.
    [B]

    f1 IS A OBJECT. You may call it a reference to an object but my experiences with talking about concepts and elements of Java is, that usually you call f1 an object.
    If you have pointers like in C++, you may need a distinction between pointers and references, but you needn't import this distinction to Java, because we have no pointers.
    In my Opinion both are objects (f2 and f1), (in this case: the same object). You may call it references - and from time to time I do it myself - but you cannot say, that "that's not what's really going on".
    You say 'f1 points to a Foo object in the heap' - so if you think there is a foo-object on (or in) the heap, let's call it f1 , because that's it's name.

    [b]
    Suppose following class:

    (Lines 8.*0 are formerly known as 8.*)


    If someone calls Gooz.gooz (), Object f is created in Line 8360, a Foo, which contains 2 Bars.
    In Line 8364 it is set to null, but might not be gc-ed - it is needed in Line 8368 again.
    In Line 8380 this Foo f runs out of scope, and might be gc-ed.
    It cannot be referenced from anywhere.
    Those Bars b1, b2 are ready for gc too.
    [/B]
    Remember, the reference is not the object.
    On line 83600, an Object is created which ontains two Bars.

    YES, yes, yes

    On line 83640, the reference to that object is lost; so the object may now be gc'ed.

    No. the two Bars inside the object may be gc-ed, because there is no reference which can reach them.
    I introduced some new lines to make my point clearer. (pleased to meet you...)
    My object g in 83605 is the same object like f.
    Perhaps it's a Pointer at adress 0x8000, pointing to 0x47900, where f is. f itself contains those bars,
    so at 0x47950 might be a reference to b1 which is at 0x8500, and at 0x47970 a reference to b2 ...
    I guess, that in line 83680, where a new Foo is assigned to f, the adress of f (0x8000) is still the same, but might point to another location - let's say 0x8100.
    Now my object g comes to the scene. g was told to be f. Will line 83705 work? (Yes, I tested it.)
    I guess we don' t differ to much, in what we believe what is happening, but how to express this.

    Since you don't work directly with objects but instead manipulate them through reference to those objects, you simnple can't do things like this in Java--it doesn't make syntactic sense.


    [/QB]
    I could tell you, that there are 'no real objects in c++' (especially not in 'c' - because c++ is based on c which is based on assembler, and there are no objects in assembler.
    It would be similar to tell, that houses aren't really build of bricks, but of walls, which are made of molecules.
    Somehow this tread started on garbage-collection, and to bring it back, my whole concern was, to point out, that f, after setting it to null (line 83640) might NOT be gc-ed.
    (Whereas the inner f.b1 and f.b2 might be gc-ed.)
     
    Stefan Wagner
    Ranch Hand
    Posts: 1923
    Scala Postgres Database Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Jim Yingst:
    One other point I haven't seen addressed (though I might've missed it):

    No, there's no way this could throw a NullPointerException, regardless of whether s was null or not. The reference s is definitely there; it hasn't been garbage collectied or anything - it's a varable which may be assigned a value. In this case, it's being assigned the value of a reference to the "Am I null" object.

    So therefore I wrote 'WOULD have been bad'.
    Since the gc will not run, we cannot figure out, whether this could throw a NullPointerException, and therefore you' re right.
    But is "Am I null" an object? In my opinion: no.
    It's a literal constant. It has no methods and no attributes. It's just values. Only in conjunction with 's' we can talk about an Object.

     
    Joel McNary
    Bartender
    Posts: 1844
    Eclipse IDE Ruby Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    >>On line 83640, the reference to that object is lost; so the object may now be gc'ed.
    No. the two Bars inside the object may be gc-ed, because there is no reference which can reach them.
    I introduced some new lines to make my point clearer. (pleased to meet you...)
    My object g in 83605 is the same object like f.
    Perhaps it's a Pointer at adress 0x8000, pointing to 0x47900, where f is. f itself contains those bars,
    so at 0x47950 might be a reference to b1 which is at 0x8500, and at 0x47970 a reference to b2 ...
    I guess, that in line 83680, where a new Foo is assigned to f, the adress of f (0x8000) is still the same, but might point to another location - let's say 0x8100.
    Now my object g comes to the scene. g was told to be f. Will line 83705 work? (Yes, I tested it.)

    In line 83645, you state that "g is null too." This, I think, is the source of the confusion. At this point in the code, g is not null. g is still pointing to the same object that f was originally pointing to. (Thereby ensuring that the object will not be garbage collected, since there is a reference to it.) The call to g.foo() will be called on the Foo object created in line 83600, not the one in line 83680.
    Consider:

    What will be printed out on the screen in lines 83720 and 83725? If g were set to null along with f in line 83640 and then "re validated" in 83680, you would expect to see
    Hello
    Hello
    Instead, what you get is:
    Hello
    World
    Because g is still referencing the object created earlier.

    Somehow this tread started on garbage-collection, and to bring it back, my whole concern was, to point out, that f, after setting it to null (line 83640) might NOT be gc-ed.

    I agree that this thread is a bit off topic, but only just a bit. I'm just trying to make the point that setting f to null will allow the object "pointed" to by f to be garbage collected. Although, admittedly, in the latest example it will not be -- but not for the reasons that you give. The reference is still needed, but when the object has no references pointing to it, it will be eligible for gc.
    And the reason I'm making a big deal about this is that people studying for certification read these forums. I don't really want them to go away confused, and this is turning into quite the thread on references and how they interact with the garbage collector.

    But is "Am I null" an object? In my opinion: no.
    It's a literal constant. It has no methods and no attributes. It's just values. Only in conjunction with 's' we can talk about an Object.

    Actually, it is an object, and can be treated as such. In fact, it often is, to prevent NullPointerExceptions when doing comparisons of strings:
     
    Jim Yingst
    Wanderer
    Posts: 18671
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    [B]
    [Jim]: No, there's no way this could throw a NullPointerException, regardless of whether s was null or not. The reference s is definitely there; it hasn't been garbage collectied or anything - it's a varable which may be assigned a value. In this case, it's being assigned the value of a reference to the "Am I null" object.
    [Stefan]: So therefore I wrote 'WOULD have been bad'.
    Since the gc will not run, we cannot figure out, whether this could throw a NullPointerException, and therefore you' re right.[/B]
    No, GC is completely irrelevant; there is no way this statement could ever throw a NullPointerException.
    [Stefan]: But is "Am I null" an object? In my opinion: no.
    It's a literal constant. It has no methods and no attributes.

    It's a literal constant that represents a String object. That object certainly does have methods and attributes:
    System.out.println("hashCode(): " + "Am I null".hashCode());
    System.out.println("length(): " + "Am I null".length());
    It's just values. Only in conjunction with 's' we can talk about an Object.
    No, this is a fundamental error pervading your other comments as well. s is not an object, it's a reference to an object. The object is really a separate thing from the s reference. Often we speak about references and objects interchangeable, because the name of a reference is a convenient way to refer to the object it references. (It's easier to say "s" than it is to say "the String referenced by s"; we're lazy.) But when we talk about garbage collection it becomes necessary to speak more precisely and distinguish between objects and references.
    This may seem like a digression from what you want to talk about, but it's a fundamental error in understanding which is apparently preventing you from understanding how garbage collection really works. So I really think it's appropriate and necessary for you to understand this.
     
    Stefan Wagner
    Ranch Hand
    Posts: 1923
    Scala Postgres Database Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Joel McNary:

    In line 83645, you state that "g is null too." This, I think, is the source of the confusion. At this point in the code, g is not null. g is still pointing to the same object that f was originally pointing to. (Thereby ensuring that the object will not be garbage collected, since there is a reference to it.) The call to g.foo() will be called on the Foo object created in line 83600, not the one in line 83680.

    Of course you're right.
    Shame on me!
    It's so obvious!
    But I was very sure while writing this down.
    Perhaps this happened because I compared references with symbolic links in the linux file-system. This comparison went too far .
    Thanks to your endurance.

     
    Joel McNary
    Bartender
    Posts: 1844
    Eclipse IDE Ruby Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Not a problem. We're here to help
     
    A "dutch baby" is not a baby. But this tiny ad is baby sized:
    Gift giving made easy with the permaculture playing cards
    https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
    reply
      Bookmark Topic Watch Topic
    • New Topic