3

I wrote an app for the production team to measure their scores, it runs fine for 2-3 weeks and then the machine that the copies are running on slows down and a restart fixes it.

What are the best practice steps for fixing this?

3
  • What do you mean by "the machine... slows down"? Are you restarting the physical server or the java process? Commented Sep 30, 2011 at 16:39
  • get a debugger/profiler that shows memory usage and such Commented Sep 30, 2011 at 16:42
  • 2
    check here olex.openlogic.com/wazi/2009/how-to-fix-memory-leaks-in-java Commented Sep 30, 2011 at 16:45

4 Answers 4

4

You need to analyse the Heap and find out what objects are being retained in there that shouldn't be.

One option:

Try reducing the -Xmx max heap size to expedite an out of memory exception, add this option to the jvm at startup -XX:+HeapDumpOnOutOfMemoryError and then load the heap dump that is generated into something like Eclipse Memory Analyzer.

Another option:

Dump the heap from your running process using jmap (probably needs sudo privileges)

jmap -heap:format=b <pid>

and again, load the heap dump binary into jhat or Eclipse Memory Analyzer.

If your app is slowing down but not throwing an OutOfMemoryError it is likely that you don't have a leak but you do need to do some JVM tuning because it's spending too much time doing GC.

You should be monitoring GC collection times (you can log them using -Xloggc:/tmp/gc.out) or you can use jstat to see how often GC takes place and how long it takes.

If you have an application with lots of medium lived objects is the Young Generation big enough (-XX:NewRatio=N) ? If not your app will spend to long promoting objects to the old gen only to have to GC them shortly after (GC in old gen is expensive relative to New Gen, especially when you have fragmented memory).

Also - have you enabled the CMS collector? If you have a multi-core machine I suggest you do (-XX:+UseConcMarkSweepGC).

Sign up to request clarification or add additional context in comments.

Comments

2

There are no memory leaks in Java in the traditional sense unless you are using JNI.

Memory leak in Java usually refers to creating referenced objects that you are no longer using. The symptom typically is that the memory usage of the application keeps growing. Do you see the memory usage growing?

You would do well to search for the exact same question in Google and follow the links.

The best practice to address is it usually to use a Profiler to check your allocations. It may also point at performance bottlenecks not caused by the "memory leaks"

3 Comments

Plenty of unexpected memory usage can take place such as retaining the return value of string.substring(a,b) when string was originally backed by a large character array.
This is an interesting fact. I don't think I use substring at all though in this particular app, do you mean to say that there are other operations with similar issues?
And oft sited example is of a Map that you keep filling in keys that you will never look up again. For example in a web based application if you store stuff in a map with key sessionid, or even worse, sessionid + :" + <something> so that you can look it up during the session then when the session expires those entries are just sitting there for ever..
1

You can check the memory the JVM requires by using an OS utility such as a task manager or top.

You can use a profiler to check the memory of your java code, e.g. Java VisualVM.

Keep in mind that Java uses garbage collection, so the only way of "memory leakage" is by holding references to (a lot of) unused objects. Josh Bloch's Effective Java item 6 (Eliminate obsolete object references) explains these situations and how to prevent them very well.

You can also use further methods to check for this kind of "memory leakage", e.g. static analysis and pluggable type systems or jvm memory options.

Comments

1

One good thing to track down memory issues is to enable garbage collection logging by adding the following commands to java at startup -verbose:gc -XX:+PrintGCDetails and -XX:+PrintGCTimeStamps. Then you can analyze how the garbage collector behaves, i.e. how often the GC is running, how long time it takes for the garbage collector to reclaim memory, how much memory is being reclaimed and if the used memory of your application is increasing.

Here's a document explaining the gc logging output: GC tuning guide for Java 6

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.