2

I'm developing a Java application which sometimes do some heavy work.
When this is the case, it use more ram than usually, so the allocated memory space of the app is increased.

My question is why the allocated space is not reduced once the work is finished ?
Using a profiler, I can see that for example 70mb is assigned, but only 5mb are used ! It looks like the allocated space can only grow, and not shrink.

Thanks

Christophe
  • 958
  • 12
  • 20
  • You need to wait for the GC to come along. – Cole Tobin Aug 12 '12 at 11:24
  • I've tried to wait 20min and nothing changed. I also tried to do a System.gc() – Christophe Aug 12 '12 at 11:25
  • System.gc() just calls the GC on another thread. You need to let it do it's thing. Doing nothing for 20 minutes won't call the GC. The GC is only called when RAM is needed, not when usage gets high. – Cole Tobin Aug 12 '12 at 11:27
  • Can't you call on GC.collect() to force the collection? – dineth Aug 12 '12 at 11:28
  • I believe that's correct - once memory is allocated, it's not returned to the operating system. The GC will clean up what's used, but nothing is given back for other apps to use. – duffymo Aug 12 '12 at 11:36
  • Related: http://stackoverflow.com/questions/6785754/jvm-process-vs-jvm-heap-memory-usage, http://stackoverflow.com/questions/11138723/force-jvm-to-return-native-memory – Volker Stolz Aug 12 '12 at 11:38
  • Thanks guys, it looks like there is no (simple) solution. I find stupid the memory cannot shrink... – Christophe Aug 12 '12 at 11:56
  • 70 MB is worth around $1 of memory these days. Your time at minimum wage is worth about $1 for 10 minutes. Its good to have a sense of proportion as the efficiency of your time is often more important than the re-usable memory in the machine. ;) – Peter Lawrey Aug 12 '12 at 19:30
  • Hehe thanks peter :) I know for my current project this is not a problem but for a bigger one it might be. – Christophe Aug 13 '12 at 21:26

3 Answers3

2

Usually the JVM is very restrictive when it comes to freeing memory it has allocated. You can configure it to free more agressively though. Try sending these settings to the JVM when you start your program:

-XX:GCTimeRatio=5

-XX:AdaptiveSizeDecrementScaleFactor=1
Trying
  • 14,004
  • 9
  • 70
  • 110
Yrlec
  • 3,401
  • 6
  • 39
  • 75
1

The JVM decides when to release the memory back to the operating system. In my experience with Windows XP, this almost never happens. Occasionally I've seem memory released back when the Command Prompt (or Swing window) is minimized. I believe that the JVM on Linux is better at returning memory.

Steve Kuo
  • 61,876
  • 75
  • 195
  • 257
0

Generally there can be 2 reasons.

Probably your program has memory management problem. If for example you store some objects in collection and never remove these objects from collection they will never be garbage collected. If this is a case you have a bug that should be found and fixed.

But probably your code is OK but GC still does not remove objects that are not used more. The reason for this is that GC lives its own live and decides its own decisions. If for example it thinks that it has enough memory it does not remove used objects until the memory usage arrives to some threshold.

To recognize which case you are having here try to call System.gc() either programmatically or using profiler (usually profilers have button that run GC). If used objects are removed after forcing GC to run your code is OK. Otherwise try to locate the bug. Profiler that you are already using should help you.

AlexR
  • 114,158
  • 16
  • 130
  • 208
  • Well my objects are all removed (not referenced anymore), so it's not the problem. And running gc from the profiler (yourKit) releases just a little bit of ram (around 7mb, corresponding to eden space) :( – Christophe Aug 12 '12 at 11:51