0

The operating system is running 10 virtual machines JVM. In fact, most do nothing - from time to time just doing a job. Each process allocates the 600MB of system memory. I know that practically up to 100 MB can be physically used. The remaining 500 MB for each of these processes is the memory managed by the JVM (OldGen etc). Unfortunately, my system has only 2GB of RAM and as a result most of the memory allocated land into the swap. This means that when the time comes to one of the machines - the first, swap is read to system memory for tens of seconds.

Is there any way to force the JVM to release memory to the operating system after completing the task? For example, the GC would run every 1-5 minutes and as a result process memory have been freed to the system.

I'm using: Linux x86_64 SMP, Java HotSpot (TM) 64-Bit Server VM 1.6.0

Max
  • 832
  • 5
  • 15
  • 1
    I think that's a duplicate : http://stackoverflow.com/questions/324499/java-still-uses-system-memory-after-deallocation-of-objects-and-garbage-collecti – Denys Séguret Apr 26 '12 at 13:41
  • As a precision : I've never found concrete specification on this topic but I've seen (on linux) memory freed by the process (but not much). – Denys Séguret Apr 26 '12 at 13:43
  • Why do you need separate JVMs for the tasks - why can't you just use a short-lived task that gets fired off onto a threadpool (using java.util.concurrent's ExecutorService construct)? – kittylyst Apr 27 '12 at 03:03
  • I cant use java.util.concurrent's ExecutorService because it is not a development issue. I have already delivered solution written in Java (as jars) to run under my operating system. I don't have possibility to change these jars nor classes. – Max May 18 '12 at 14:06

2 Answers2

0

This means that when the time comes to one of the machines - the first, swap is read to system memory for tens of seconds.

Memory pages are only swapped in when they're accessed. If the 500MB that you speak of were really "free" from the JVM's point of view, they wouldn't end up being swapped in. There must be a reason why the JVM is touching that memory. One possibility is that it's not really free, but contains live objects.

I would recommend:

  1. Using a memory profiler (YourKit or VisualVM) to see the actual memory usage of the JVMs.
  2. Possibly tweaking the size of the heap with -Xmx.
NPE
  • 438,426
  • 93
  • 887
  • 970
0

I am not an expert in performance issues, but let me try to help you with this.

There is a call to the garbage collection system that is System.gc(). If you consult the official documentation for the class System (http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/System.html) it will tell you that this method runs the garbage collection.

Nevertheless, if you consult the Internet (such as When does System.gc() do anything) you will see that this call MAY call the garbage collection system. My personal experience agrees with that post.

Since memory management is automated, the garbage collection system will go to to great lenghts to do a good job of managing the memory for you. Management algorithms are quite efficient and trying to outsmart them usually does not get you great results.

You stated that most machines do nothing - hence, why not "kill" them and start a new one when you have a job? Wouldn't that be more efficient?

Community
  • 1
  • 1
rlinden
  • 2,005
  • 1
  • 11
  • 13
  • Oh yes! It would be great, but I forget to say that processes had internal triggers - not external. So JVM had to be run, because no others know when trigger fire:-) – Max Apr 26 '12 at 13:58