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

about Garbage Collector logic.

 
Ranch Hand
Posts: 106
Mac Mac OS X Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.

help me guys?
 
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Lucas Franceschi
Ranch Hand
Posts: 106
Mac Mac OS X Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.

 
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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().
 
Lucas Franceschi
Ranch Hand
Posts: 106
Mac Mac OS X Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.

right?
 
Rob Spoor
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Lucas Franceschi
Ranch Hand
Posts: 106
Mac Mac OS X Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
yeah, that explais also what iteration means.

so, calling system.gc() would be a good idea...

can anyone wonder why?
 
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
To me, Rob's response implied that calling gc() doesn't make a huge difference in memory, but *does* make a significant difference in performance.
 
Lucas Franceschi
Ranch Hand
Posts: 106
Mac Mac OS X Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.

am i wrong?
 
David Newton
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Java will GC if it needs more memory. That's one of the points of GC languages--it's relatively rare that we need to provide such hints.

Not saying there aren't any circumstances under which we might need to call it, or that calling it manually is intrinsically bad.
 
Lucas Franceschi
Ranch Hand
Posts: 106
Mac Mac OS X Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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"...

anyone with me?
 
David Newton
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What I'm saying is that calling GC is unlikely to prevent an OOM error: Java will call GC itself if it needs more memory. OOM errors occur when it can't allocate enough.
 
David Newton
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Also note that just because you *call* System.gc() doesn't mean GC will be done.
 
Lucas Franceschi
Ranch Hand
Posts: 106
Mac Mac OS X Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
ok, thank you!
 
Think of how stupid the average person is. And how half of them are stupider than that. But who reads this tiny ad?
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic