View Full Version : Hello - Garbage Collector
Pinball
06-06-2002, 07:36 PM
Greetings to everyone, since this is my first post, I will -shortly- introduce myself, my name is Matias, Iīm 20 years old, I live in Buenos Aires, Argentina (which is the reason for spelling mystakes in this and future posts), Iīm a CS Student, Iīm learning Java.
Ok, that said, here is my question about the Garbage Collector:
I know that happens when something like this is coded:
[ code ]
public static void main(String[] args)
{
MyObject a = new MyObject();
MyObject b = new MyObject();
b = a;
}
[ /code ]
If I got it right, the refence to a is lost, so the Garbage Collector canīt "collect it".
However I've seen this somewhere:
[ code ]
public static void main(String[] args)
{
BufferedReader fileIn = new BufferedReader(new FileReader
(new File("somefile")));
String fileLine = null;
while( (fileLine = fileIn.readLine()) != null)
System.out.println(fileLine);
fileIn.close();
}
[ /code ]
Now, isnīt a reference to the String fileLine lost every time the loops ask for a line? If so, what would be a good way to procces a text file?
Thanks in advance for any replies...
Dru Lee Parsec
06-06-2002, 08:04 PM
Hello Matias: Welcome to Coder Forums.
In your first example there is this line:
b = a;
In that line the original reference to "b" is lost. So yes it will be garbage collected at some point. Realize that unless you make a call to
System.gc();
then you don't know exactly when it will be garbage collected, just that it will be.
Let's look at your 2nd example:
public static void main(String[] args)
{
BufferedReader fileIn = new BufferedReader(new FileReader
(new File("somefile")));
String fileLine = null;
while( (fileLine = fileIn.readLine()) != null) {
System.out.println(fileLine);
}
fileIn.close();
}
I added a set of curley braces to more clearly show that the System.out.println is the only thing being executed within the while statement.
In this case the String fileLine is constructed only once. The code inside the while loop is simply reassigning the value of fileLine. fileLine will be flagged for garbage collection when the main method ends because it goes out of scope.
It's easy to get confused with a String class because String is an object that can be instantiated on the heap with
String s = new String("Hello");
Or on the stack like this:
String s = "Hello";
It's also the only class that has operator overloading :
String y = s + " World";
So it's confusing to think of assigning references with a String class just because the String class breaks so many of the rules that other classes in Java must conform to.
Hope it helps.
Dru
P.S. I think the extra space in your code tag is why it didn't display properly.
DukeofNukes
06-06-2002, 09:56 PM
Originally posted by Dru Lee Parsec
It's easy to get confused with a String class because String is an object that can be instantiated on the heap with
String s = new String("Hello");
Or on the stack like this:
String s = "Hello";
[/B]
OK, I haven't taken a data structures class yet, but I've never even heard of a heap. What is it, what's it for, and how's it different from a stack?
::enthusiastic 'cause he's gonna learn somethin'::
Dru Lee Parsec
06-06-2002, 10:25 PM
It's easier to think of heap and stack in terms of C or C++ rather than Java.
If you create an int like this:
int x = 5;
Then it was created on the "Stack". The stack is a part of memory that handles variables and return addresses within a method. For example, if you have this method:
void foo(int y) {
int x = 5;
cout << "x is " << x << " and y is " << *y << endl;
}
when that method hits the closing brace then the int x (which was created on the stack) is released from memory. The next thing down on the stack is the address of y (since it's an int pointer) and the next thing down is the memory location of the program where the program flow should return to when this method is done.
Now, the "heap" is a section of memory that is separate from the stack. In C this is where your malloc get's it's free memory or in C++ it's where "new" get's it's memory. This memory is only freed up by a "free" or "delete". You use the heap when you want to create an object that is passed around between different objects or methods and you want it to stay "alive" until you say otherwise.
Let me know if that clears it up. If not I could explain the ins and outs of stack and heap a bit better if I sit back with a beer and think about what I'm going to write before I write it ;)
DukeofNukes
06-06-2002, 11:37 PM
Aight, lemme say that back in my own words and see if I got it right.
The stack is primarily used for local variables, and those variables get popped off (or simply bypassed) to go back to the memory location the program was at before it ran that method.
The heap is another, separate memory area that's used for enduring, global variables and objects, and references on the heap only go away when they are deliberately disposed of. How's the heap constructed? Is it a stack-like, LIFO data structure, or something (as the name implies) less strictly governed? In Java, does something get yanked off the heap when all pointers to it are removed, or does it continue to exist in memory until the program ends. I wouldn't think the latter is the case, simply for issues of memory allocation.
Woohoo! Learning has commenced! And my buddies wonder why I dislike going to my syntax -- not concept -- laden programming classes.
In C/C++, memory is removed from the heap when it is freed, via a free(void*) in C or a delete in C++, in java it goes away when the Garbage Collector gets "awakened" by the Java Virtual Machine. I don't know if that's implementation-dependent or not.
So, don't think of the heap as a data structure, because you never deal with it directly in your code. Either the OS or JVM deals with it.
Oh, and welcome Pinball. :)
Pinball
06-07-2002, 12:26 PM
Thanks, for the replies, but still thereīs something I donīt get:
Letīs say the file contains these lines:
Hello java world 1
Hello java world 2
(eof)
Where am I wrong?:
fileLine contains null, the while condition is examined so
readLine() is called, readLine() returns a reference to a new String containing "Hello java world 1", which is assigned to fileLine, the line is printed, the condition is examined again so readLine() is called, returns another reference to a new String containing: "Hello java world 2" which is assigned to fileLine which contained a reference to "Hello java world 1". (Isnīt the reference to "Hello java world 1" lost?)
I mean doesnīt this happens?:
public static void main(String[] args)
{
BufferedReader fileIn = new BufferedReader(new FileReader
(new File("somefile")));
String fileLine = null; // fileLine is now null
fileLine = fileIn.readLine(); // fileLine is now a reference to line 1
System.out.println(fileLine);
fileLine = fileIn.readLine(); // fileLine is now a reference to line 2
// so reference to line 1 is lost
System.out.println(fileLine);
fileIn.close();
}
I know Iīm missing something but canīt realize what...
Thanks again for the welcomes and replies
I guess I don't understand what your problem is. Yes; to you, the reference to line 1 is lost, but the garbage collector, knowing that you have no more references to that object, will eventually clean it up.
DukeofNukes
06-07-2002, 04:16 PM
I guess what I'm really asking is, "How does the heap do what it does?" Granted that I'll never directly deal with it, I've found that understanding how the stack works on a very low (assembly language) level helped me understand how the higher-level languages function and improved the efficiency of my code.
The heap doesn't do anything. It just sits there. Your OS will give your program some heapspace, and your program can allocate that space for specific variables (via pointers) and deallocate it when it's done. In java you don't deal with it as directly as you do in C/C++. The JVM will allocate the proper space from the heap when you create a new object, and when you have no more references to that object, it will clear the space, making room for new objects. The heap, afaik, is about as unstructured as it gets. You get a chunk of memory, and you use bits and pieces of it for dynamic variables. You never really deal with it directly (for example, you never say "I want this array to take up the first 100 bytes in the heap")... you just make a function call (new, alloc, malloc, etc.) saying "I want 100 bytes". In C(++) if you never say "Okay, I'm done with this 100 bytes", then it won't get cleaned up until your program exits.
edit fixed typo and made myself a little more clear
Dru Lee Parsec
06-07-2002, 05:38 PM
Yes; to you, the reference to line 1 is lost, but the garbage collector, knowing that you have no more references to that object, will eventually clean it up.
I still think that all that is happening is that the value of the data in the memory space allotted to String fileLine has been changed. So rather than losing a reference to line 1 you're really just reassigning the value of the variable. You still have a reference to the same place in memory, it just has different data there.
If this object wasn't a string then you could print out it's address. But in Java the String object has it's toString method overloaded (by definition) to return the value of the string. But if you could see the address of the string then I bet you would see that code like this:
String s = "";
s = "Foo";
s = "Bar";
doesn't change the object's memory address, just the value of the object. Again, the String class is a difficult class to use to explain this idea because a String is really a wrapper for a class that will allocate and free up memory as it is needed to hold different size strings of characters.
But as Duke and Kmj have said, Java will clean up for you anyway so it's not an issue from a "better code" standpoint. It's only an issue from an understanding point.
BTW, Duke, I agree with your assessment of ASM code. When my assembly language teacher told us "The first thing you need to put on the stack is the return address of the operating system" the whole concept of a stack made sense.
DukeofNukes
06-08-2002, 03:04 AM
Best class I've taken yet, in terms of being a better programmer, was an electrical/computer engineering survey class that went from construction of transistors to using them to build logic gates to building complex logical circuits from gates to putting those circuits together into simple processors and memory to coding basic binary instructions for those simple processors to rewriting that binary as ASM, to translating between basic C and ASM. I learned more about how the box actually works, and how to get it to work well, than in any three other courses combined.
Pinball
06-08-2002, 05:54 AM
I guess I don't understand what your problem is. Yes; to you, the reference to line 1 is lost, but the garbage collector, knowing that you have no more references to that object, will eventually clean it up.
My problem is that, if in the first example of my first post the garbage collector doesnīt clean the lost reference why would clean it in the second example.
I still think that all that is happening is that the value of the data in the memory space allotted to String fileLine has been changed. So rather than losing a reference to line 1 you're really just reassigning the value of the variable. You still have a reference to the same place in memory, it just has different data there.
I donīt think that happens, try this:
String s = "";
String t;
s = "Foo"; // s is a reference to "FOO"
t = s; // now t is a reference to "FOO"
s = "Bar"; // now s is a reference to "Bar" which is
// at a diferent address
System.out.println(s);
System.out.println(t);
Moreover I think in your example a reference to the "FOO" String is lost and that the garbage collector canīt clean it up.
Dru Lee Parsec
06-08-2002, 01:58 PM
No, you did not lose a reference to "Foo", you simply re-assigned the value of s to "Bar".
To lose a reference you would have to do this:
String s = "Foo";
s = new String("Bar");
In this case you reassigned the memory location that s refers to. In your example can you get "Foo" back from s? No. But that's no different that this code
int x = 5;
x = 7;
Did you lose a reference to the 5? No, you just reassigned the value of x. Can you get the 5 back from x? No. But that doesn't mean you lost a reference to it.
In programming the word "reference" has a very specific meaning. It means "an address of an instance of a data type" (which coincidentally is also the definition of a pointer in C) To "lose a reference" means that the address of an object has changed. A Java String does not change memory locations when you re-assign it's value. Therefore you do not lose a reference to it.
Pinball
06-08-2002, 06:30 PM
OK, the output of:
String s;
String t;
s = "foo";
t = s;
s = "bar";
System.out.println(s + "\n" + t);
is:
bar
foo
Hereīs what I understand from it:
t and s are pointers (often called references because java is not supoused to have pointers), 's = "foo" ' saves in s a reference to an object (in this case a String) which contains "foo".
't = s' saves in t the same reference saved in s ("foo"). 's = "bar"' saves in s the address of a diferent String ("bar").
If like you said:
A Java String does not change memory locations when you re-assign it's value. Therefore you do not lose a reference to it.
The output of the above code should look like:
bar
bar
but it doesnīt, so I believe that a Java String DOES change memory locations when I reassign itīs value. Therefore the reference IS lost.
Pinball
06-08-2002, 06:38 PM
Therefore the reference IS lost.
I meant the reference to an object (String) containing "foo" is lost in this code:
String s = "Foo";
s = "Bar";
Strike
06-08-2002, 07:14 PM
In that code, there would be no more reference to an object containing that string, because where there was initially memory holding the string "foo", that memory has since been changed to hold "bar".
Pinball
06-08-2002, 07:58 PM
If so, then why the output of:
String s = null;
String t = null;
s = "foo";
t = s;
s = "bar";
System.out.println(s + "\n" + t);
is this?:
bar
foo
I mean if THAT memory has changed to hold "bar" both, s and t, would be references to a String holding "bar", and the output would be:
bar
bar
Pinball
06-10-2002, 09:09 AM
Ok, I believe kmj is right:
Yes; to you, the reference to line 1 is lost, but the garbage collector, knowing that you have no more references to that object, will eventually clean it up.
I īve tried this out:
String s = null;
for(int i = 0 ; i < 10000 ; i++) {
s = "bar";
System.out.println(Runtime.getRuntime().freeMemory());
}
As you may see if you try this out, the amount of free memory keeps decreasing, until it goes back up to a certein value to then decrease again.
So I beleive NEW objects are being created in another memory address.
If you try this other one:
int j = 7;
for(int i = 0 ; i < 10000 ; i++) {
j = 8;
System.out.println(Runtime.getRuntime().freeMemory());
}
Youīll see, after a few executions, that the amount of free memory keeps the same as expected since primitive types arenīt placed dynamically.
Dru Lee Parsec
06-11-2002, 12:22 PM
OK, I still maintain that there is a subtle but important difference that you are missing. But then again I've only been writing code for 30 years and I've only been writing Java code for 4.5 years so WTF do I know?
So fine, believe what you want. But if it was possible to see the memory location of an instance of a String class you would see that this:
String s ="Q";
s = "R";
would NOT change the memory location where s resides. Internally, the String class may have reassigned memory (which is what you are seeing with the memory usage) But remember the a String is the ONLY CLASS IN JAVA that has the = and + signs overloaded. With a String the = sign is an assignment of data, not an assignment of the memory location of the object.
With EVERY OTHER CLASS IN THE LANGUAGE the schema you are proposing is true. However, it's not true with a String. This is why I wrote :
Again, the String class is a difficult class to use to explain this idea because a String is really a wrapper for a class that will allocate and free up memory as it is needed to hold different size strings of characters.
Pinball
06-12-2002, 12:52 PM
I would like to apologize for being stubborn and not 'listening'. My attitude wasn't appropiate for someone who is asking for help to understand something. I just kept posting the same which after re-reading sounds stupid.
I think I got it right, sorry...
vBulletin® v3.7.0, Copyright ©2000-2009, Jelsoft Enterprises Ltd.