• 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

Why does invoking System.gc() lead to a significant decrease in memory usage?

 
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have a long-running JVM Spring server application that undergoes continuous processing. I've noticed a gradual increase in memory usage over time, but it never leads to a JVM out-of-memory crash. However, when I manually generate a heap dump, I observe a significant drop in memory usage, returning to the initially expected levels. When i analyze the dump i dont see anything unusual because probably dump is generated with garbage collecetd memory. As i know this drop occurs because generating a heap dump triggers the garbage collector to work.


To test this behavior, I tried calling System.gc(), and it reproduced the memory drop. I'm curious about why this happens. Why does JVM not perform this garbage collection automatically? It appears that, for some reason, it doesn't do so without me explicitly forcing it to clear. But as i mentioned this does not cause JVM crash. Probably it releases that memory when it needs it. This is an autoscaling application running on Kubernetes, and this behavior results in the unnecessary creation of additional instances due to the memory increase.


Is there a parameter which i can pass to JVM related to this behaviour?


I expect JVM to clear memory automaticly without me explicitly calling System.gc()
 
Saloon Keeper
Posts: 7576
176
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The JVM does indeed reclaim available memory automatically (as you observed, since your app never runs out of memory). Often it will only reclaim smaller amounts of memory than what calling gc() would reclaim (because smaller collections take less time and CPU), but sometimes it does indeed do a full GC.

I'm not aware of any switches that would aid in container environments, but maybe others have experience in this area.
 
Saloon Keeper
Posts: 27720
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Your exact results will depend on what version and brand of JVM you use, but one popular garbage management method involves incremental collections instead of one big sweep. Though you may see several different strategies running for a given JVM depending on what's being collected.

I suspect, however, that one of the best ways to avoid "wasted" JVM memory is simply to reduce the maximum memory allocated to the JVM at startup. It's entirely likely that the sweep gc is being triggered when the uncollected garbage reaches a certain level of the JVM's total allocated memory.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic