7

Suppose I have a Swings Java Application, I set the min Heap is 64MB and max Heap 2GB, when the user start the application, the log in screen will be displayed, at this time the app uses 64MB, rights? From my Windows 7, I can see the java application is allocated 64MB from the Memory Resource Monitor of the OS (actually, it's more than 64MB because JVM need some memory for it's task).

After that the user does some very heavy job then the application uses 2G. Then the user log out the application, the log in screen is displayed again (the application is not closed yet). At this time the real memory that the application is using 64MB (suppose this is the perfect memory management application), but with the OS this application is still using 2G of RAM, I can see it on the resource monitor of the OS.

I want my application release the memory to the OS when it doesn't need to use a big memory. Can I do it at runtime with java app?

I mean when my application need to use 64MB of Ram, then the OS gives it 64MB only, when it need 2GB of ram then the OS gives it 2GB, after that it need 64MB of ram then the OS gives it 64MB only again, I don't want it waste 2000MB - 64MB = 1936MB.

Can I do that?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
user1592936
  • 71
  • 1
  • 2

5 Answers5

5

I want my application release the memory to the OS when it doesn't need to use a big memory. Can I do it at runtime with java app?

No you can't.

Under some circumstances, the GC will release memory back to the OS of its own accord, but I'm not aware of any JVM that allows an application to tell the GC to do this. And on top of that, the GC is rather conservative about doing this because ... as a general rule ... the JVM will operate more efficiently with more memory, and continually requesting / giving back memory to the OS is inefficient.


Note that the GC tuning option -XX:MaxHeapFreeRatio can be used to specify the maximum ratio of free to used heap before the GC will give memory back. However, there are complications. For example, not all available GCs respect this option. If you are going to try this approach, I suggest you do some research ... and don't expect miracles.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 1
    Is it a matter of GC? I don't think so. The GC clears the objects and frees the heap but disposing heap is something else. – Amir Pashazadeh Aug 12 '12 at 05:51
  • @AmirPashazadeh - you'd need to read the JVM source code to know where the code that gives back memory actually is. – Stephen C Aug 12 '12 at 07:33
  • 1
    Please note that this settings is only considered when the singeThreadGC is used. I found that out in this answer http://stackoverflow.com/a/8170123/775513 after not observing any behaviour changes when using this option. – cproinger Aug 06 '14 at 09:31
  • @cproinger - I think you should be careful about generalizing from that Q&A. The Question is about the behaviour of a Java 5 JVM. A lot has changed in Java memory management / garbage collection since then. – Stephen C Aug 06 '14 at 10:15
5

I have posted my test results over there. Basically, MaxHeapFreeRatio is not respected by every GC implementation, and, to make it worse, it seems to be necessary that there is enough heap activity in order to trigger it in a timely manner, ie. could be that you require 2 full GC runs to actually release the memory to the OS. And if you have a burst memory footprint of X GB, then you probably have to allocate 1 or 2 times of that amount in order to trigger the heap downsize. Or you call System.gc() manually.

If performance is not an issue, and memory footprint is all that counts, try:

-XX:UseSerialGC -Xms16M -Xminf=5 -Xmaxf=10
user1050755
  • 11,218
  • 4
  • 45
  • 56
  • Interesting blog. Good work. However I would like to know for how long time you've waited. Example: How would the JVM memory consumption be (as seen from the OS) after you've done your loops and hoops and then went idle for say 1 hour? By 'idle' I mean no memory alloc activity. – peterh Oct 17 '13 at 06:32
  • AFAIK the GC is triggered by memory changes.... so just waiting will not do anything at all. Try it yourself, the code is there. – user1050755 Aug 07 '14 at 10:28
  • Interesting post. By the way, it seems that for Oracle and IBM VMs, values for `Xminf` and `Xmaxf` should be percentages (from 0.0 to 1.0) and without the leading `=`. See [here](https://docs.oracle.com/cd/E19683-01/806-7930/filestructure-8/index.html), [here](http://www-01.ibm.com/support/knowledgecenter/SSYKE2_7.0.0/com.ibm.java.lnx.70.doc/diag/appendixes/cmdline/xmaxf.html), and [here](http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8025661). – xav Nov 29 '14 at 20:21
  • In my opinion, what makes the VM release memory back to OS is only `-XX:UseSerialGC` in your example since `Xminf` and `Xmaxf` are ignored due to bad syntax (see my previous comment). With a correct syntax, you can indeed tune this release with `Xminf` and `Xmaxf`. – xav Nov 29 '14 at 20:31
  • I'm only using Sun/Orcale JVMs. It works there. If you use anything special, it is of course up to you to check it. – user1050755 Jan 13 '15 at 12:06
2

The serialgc in hotspot will give memory back... at least it used to. Your performance will nose dive.

All of the garbage collectors in IBM J9 jvm will release memory. I'm not sure this jvm is a free download...

The best answer is, why are you concerned? Memory is dirt cheap these days and free memory is wasted memory. Is this actually a problem? The OS will page the extra unused memory to disk anyway. The best answer is to ignore it. :)

You might also consider Googling off-heap storage, perhaps Teracotta/eh cache.

EDIT:

I just noticed in JDK1.7u6, that using G1GC with a small Xms and large Xmx, the garbage collector will reduce the size of the heap after a few garbage collections where excess objects have been freed.

Jonathan S. Fisher
  • 8,189
  • 6
  • 46
  • 84
  • 2
    Because my client didn't like it. In 99% cases they did the job which consume about 300 - 400MB of RAM. There's 1% cases where they did some heavy job then the application uses 2GB of RAM. And they said that my application use too much memory when it is not necessary to do that. They need memory for another apps. It seems that whenever a java app run in the maximum memory using, it will not give the memory back to the OS when it runs in the minimum memory using. Is it right? – user1592936 Aug 12 '12 at 09:28
  • 1
    see update, I discovered some new info... :) I'm sorry your client is so picky, they shouldn't be. They should rely on their operating system to manage the memory correctly. – Jonathan S. Fisher Aug 30 '12 at 18:54
  • Well it isn't unreasonable to ask that java handles memory correctly also (and I say this as a java developer). I don't agree in general that holding onto 5-10 times the memory currently required indefinitely, or even for a prolonged period, is correct behavior unless there is nothing else running on the machine. – nsandersen Dec 09 '16 at 17:45
  • It **is** correct behavior. The incorrect behavior is people's understanding of how memory works. You'd be shocked to discover what's actually physically happening with the JDK, garbage collector, and the page table on your system. It's all a grand illusion :) – Jonathan S. Fisher Dec 12 '16 at 20:15
  • 1
    "Memory is cheap" is a great line, as long as you've got additional slots. Talk to me when you're running 256GB/slice and want 3-4 java programs to run at the same time in a VM/container. If any one of them takes a huge chunk of memory, it can cripple the others. Either that or you artificially limit them to a fraction each, thus wasting resources just in case they're needed elsewhere. It's a lose-lose. – Basic Aug 17 '17 at 10:20
1

You can dispose of objects and suggest the garbage collector do its work, but if the GC does not feel it is necessary, the request will be ignored. So in summary, 'no'.

Note that memory assigned to Java apps. is set before the app. starts, and is not adjustable.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
0

Try forking parts of your code to a separate thread and dispose it when you don't need it anymore.

Benvorth
  • 7,416
  • 8
  • 49
  • 70
  • This makes little sense in the context of Java. (And if you are referring to Java threads, then this is not going to achieve what the OP is trying to do -- convincing the JVM to give heap memory back to the OS.) – Stephen C Mar 29 '15 at 11:19