Its been a long time since my last question here guys, but always that I need, you help me, so I'm back...
the question now is not that complex or anything (if you see i've posted in begginners forum), its just about logic...
What is the logic of garbage collection, when dealing with loops?
Lets consider the following:
In this case, for each key i will loop again, and create three variables.
The question is: when one lap of this loop is finished, what happened to the variables created? My understanding is that the objects created in one lap, are, on the end of this lap, classificated as garbage, and so it should be collected. If its correct, when i loop a hundred thousand times something, i should have a lot of garbage, so it would take a lot of memory? would it be recommended for me to call the System.gc() method on the beginning of this loop?
please consider that i'm working with many hundred thousand laps.
You're actually creating only one new object (at most*) in each iteration: the trimmed string. The first two statements don't create any new objects; name and type are simply extra references to extra objects (assuming both keys and anotherHashMap are Maps, and get does not return a newly created object). The third statement does potentially* create a new object, but that loses its only reference immediately so the GC can collect it.
Now, you shouldn't have to call System.gc() since the GC should always run if really required; an OutOfMemoryError should only be thrown if there is nother choice.
* String.trim() actually returns the same String if it does not need any trimming.
ok, thank you for the reply, but its kinda not explained yet.
well, I haven't payed attention to the fact that i'm not creating objects, but that's another case,
in other topic maybe we talk about the trim() method, it is, as well, another case.
it is important, but lets pay attention to the real problem.
assume that i'm creating three objects, and repeat the question.
I've just run a test, and the thing is:
-I had a full class without the System.gc() method being called.
-It held 800M of memory (yes, 800M)
-i used System.gc() on the beginning of every loop
-it held 200M of memory (yes, 600M less than before)
so i'm thinking that garbage collector does not work that well everytime. You said that it runs when really needed, what if java is weak on knowing when to GC? because in the class i had (the one that hel 800M of memory), i had OutOfMemoryError, as soon as garbage got excessive, and calling GC manually resulted in 600M of memory saved.
i dont want to be 'not-cool' with you guys, but we need to look at the real problem.
Can you show us the test that you ran? We can assume you are creating new objects, and that you aren't talking about String#trim(), but then the code you are talking about has nothing to do with the code you posted, so it is hard to come up with a reasonable response. But if you showed us the code you ran that gave you these results, then we can talk more intelligently on where the extra memory may be going and why you may or may not need to manually call gc().
but then the code you are talking about has nothing to do with the code you posted
ok, sorry for that, lack of attention.
the test i ran was about running the program with and without the manual calling of GC, i'm sorry i can't give you a better example, so i'll try to do something really simple:
ok I think this time the code is better.
looking at the code:
1.for every loop, i'll create a new hashmap, put values to it, and pass it to another method as a parameter.
2.so, imagine the first lap, i created the first object, did the rest with it.
3.on the second lap, i'll create a new object, so the one i created on the first loop, will be classificated as garbage, right?
-in this case, if i dont call System.gc(), it holds a lot of memory, because of the hashmaps that was created on each loop.
-it seems that JVM dont collect garbage while i still loop, so that this garbage will be there using memory.
-if i collect the garbage on the beginning of each loop, pratically it saves a lot of memory.
I don't think that's a good example. I copied that code, modified the "x.toString()" and "i.toString()" into "new Integer(x).toString()" and "new Integer(i).toString()", and turned the other method call into a call to a method that printed out the map. After that method call I printed Runtime.getRuntime().freeMemory(), and the values were quite constantly zigzagging between 40 million and 50 million. And that included the StringBuilders used in the printing of the maps.
After adding a System.gc() at the start of each iteration (not lap ) the free memory was a lot more constant at just over 50 million. It did slow down everything quite a lot though.
hmm... you have a good point.
but what if java itself runs out of memory whithout the calls??
it would be recommended for me to slow down the performance a little, and save the memory, so that i wont need to do desperate things, such as increasing java heap space.
in this case, I believe practic ignores theory, we know you cant have an perfect software, JVM is not perfect, and by practice, i can say that jvm fails in saving memory, one time that when i call gc manually it saves me from an "OutOf MemoryError"...