2

I have such problem that jvm is not able to perform gc in time and application freezes. "Solution" for that is to connect to application using jconsole and suggest jvm to make garbage collections. I do not have to say that it is very poor behavior of application. Are there some option for jvm to suggest to it to perform gc sooner/more often? Maybe there are some other real solution to this problem?

The problem appears not to be not enough of memory but that gc is not able to do collection in time before new data is send to application. It is so because gc appears to start to collect data to late. If is is suggested early enough by System.gc() button of jconsole then problem does not occur.

Young generation is collected by 'PS Scavenge' which is parallel collector. Old generation is collected by 'PS MarkSweep' which is parallel mark and sweep collector.

Trismegistos
  • 3,821
  • 2
  • 24
  • 41

8 Answers8

2

There is System.gc() that does exactly what you described: It suggests to the JVM that a garbage collection should take place. (There are also command-line arguments for the JVM that can serve as directives for the memory manager.)

However, if you're running out of memory during an allocation, it typically means that the JVM did attempt a garbage collection first and it failed to release the necessary memory. In that case, you probably have memory leaks (in the sense of keeping unnecessary references) and you should get a memory profiler to check that. This is important because if you have memory leaks, then more frequent garbage collections will not solve your problem - except that maybe they will postpone its manifestation, giving you a false sense of security.


From the Java specification:

OutOfMemoryError: The Java Virtual Machine implementation has run out of either virtual or physical memory, and the automatic storage manager was unable to reclaim enough memory to satisfy an object creation request.

Theodoros Chatzigiannakis
  • 28,773
  • 8
  • 68
  • 104
  • 2
    Calling `System.gc()` is almost always a non-solution. Indeed, it will typically make your application less responsive while not helping at all with the OOMEs. – Stephen C Sep 10 '13 at 11:50
  • In fact I believe many JVM implimentations simply ignore System.gc() calls – Richard Tingle Sep 10 '13 at 13:02
  • The problem appears not to be not enough of memory but that gc is not able to do collection in time before new data is send to application. It is so because gc appears to start to collect data to late. If is is suggested early enough by System.gc() button of jconsole then problem does not occur. – Trismegistos Sep 10 '13 at 13:16
  • 2
    @Trismegistos Please see my edit. A GC cycle definitely occurs before the resorts to throwing the OOME, *unless your JVM isn't compliant to the Java specification* (which is unlikely). From your description, it looks like you haven't actually verified that the collection does *not*, in fact, happen - so verify that first. – Theodoros Chatzigiannakis Sep 10 '13 at 13:57
2

You should check for memory leaks. I'm pretty sure you won't get OutOfMemoryException unless there's no memory to be released and no more available memory.

strikerbs
  • 21
  • 2
  • By memory leaks I assume you mean hanging on to references for longer than you need them. A real memory leak is near to impossible in java – Richard Tingle Sep 10 '13 at 11:38
  • 1
    Yes, of course, I don't mean classic memory leaks. An example of a memory leak in java would be adding objects in a collection and not having code to remove them (e.g. storing events of a particular type). Such collections can grow infinitely and take up all your heap. – strikerbs Sep 10 '13 at 11:40
  • @strikerbs The web application that I've inherited has terrible software aging problems. Everything runs behind a framework, so figuring out where it might be happening is a nightmare. – Cruncher Sep 11 '13 at 19:23
1

You can deploy java melody on your server and add your application on it, it will give you detailed report of your memory leaks and memory usage. With this you will be able to optimize your system and code correctly.

Jhanvi
  • 5,069
  • 8
  • 32
  • 41
1

I guess, either your application requires more memory to run efficiently, try tuning your JVM by setting parameters like -Xms512M -Xmx1024M. Or, There is memory leak which is exhausting the memory.

You should check the memory consumption pattern of your application. e.g. what memory it is occupying when it is processing more vs remain idle.

If you observe a constant surge in memory peaks, it could suggest towards a possible memory leak. One of the best thread on memory leak issue is How to find a Java Memory Leak

Another good one is http://www.ibm.com/developerworks/library/j-leaks/

Community
  • 1
  • 1
Gyanendra Dwivedi
  • 5,511
  • 2
  • 27
  • 53
  • The problem appears not to be not enough of memory but that gc is not able to do collection in time before new data is send to application. It is so because gc appears to start to collect data to late. If is is suggested early enough by System.gc() button of jconsole then problem does not occur. – Trismegistos Sep 10 '13 at 13:18
  • The JVM attempt to re-claim all sort of memory before it fails. So, it should not fail unless you have a bug in JVM implementation. Here, I believe you are using one of the standard JVM implementation or server tool. If it is so, there could be only issue with application code. Do one thing, increase the heap space parameter and watch for the OOM error. It would not occur soon, but if it occurs after a later time, it indicates towards a possible memory leak. – Gyanendra Dwivedi Sep 10 '13 at 13:40
  • If it was problem with memory leak or to less of memory System.gc() wouldnt help because it wouldn't be able to collect any memory. System.gc() helps though which shows that there is memory available. – Trismegistos Sep 10 '13 at 14:00
  • Ok.. then do one thing increase the heap size (I hope the error is not OOM - Perm Gen issue) to sufficiently large and see if your problem resolves at least temporarily. Because if it is not an issue with memory leak, the application should be running fine with a big enough memory. And must observe if the app is running fine for a longer time ; then gradually reduce the memory to see the threshold till it start having OOM issue. – Gyanendra Dwivedi Sep 10 '13 at 14:18
1

Additionally,

you may receive an OOME if you're loading a lot of classes (let's say, all classes present in your rt.jar). Since loaded classes reside in PermGen rather than heap memory, you may also want to increase your PermGen size using -XX:MaxPermSize switch.

And, of course, you're free to choose a garbage collector – ParallelGC, ConcMarkSweepGC (CMS) or G1GC (G1).

Please be aware that there're APIs in Java that may cause memory leaks by themselves (w/o any programmer's error) -- e. g. java.lang.String#substring() (see here)

Community
  • 1
  • 1
Bass
  • 4,977
  • 2
  • 36
  • 82
1

If your application freezes, but gets unfrozen by a forced GC, then your problem is very probably not the memory, but some other resource leak, which is alleviated by running finalizers on dead objects. Properly written code must never rely on finalizers to do the cleanup, so try to find any unclosed resources in your application.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
0

You can start the jvm with more memory

java -Xms512M -Xmx1024M

will start the jvm with 512Mb of memory, allowing it to grow to a gigabyte.

Bex
  • 2,905
  • 2
  • 33
  • 36
0

You can use System.gc() to suggest to the VM to run the garbage collector. There is no guarantee that it will run immediately.

I doubt if that will help, but it might work. Another thing you could look at is increasing the maximum memory size of the JVM. You can do this by giving the command line argument -Xmx512m. This would give 512 megabytes of heap size instead of the default 128.

You can use JConsole to view the memory usage of your application. This can help to see how the memory usage develops which is useful in detecting memory leaks.

DeltaLima
  • 5,864
  • 1
  • 16
  • 32