Question

I am writing a servlet that I can't test in Eclipse, I need to run on server. I want to do memory profiling and pinpoint any leaks. So, I think I need write debug statements that can tell me current memory usage. Can someone point me to good references on how to do this and/or which classes in the JDK do this ?

Note that I can't use the "Eclipse MAT".

Was it helpful?

Solution

Can't you use the built-in tool in the jdk jvisualvm?

OTHER TIPS

JConsole to rescue you!

Profiling application memory and hunting down leaks would be a difficult task, not to mention misleading with simple debug statements. If you can't use a tool which remotely connects to your process, using hprof would be a good bet IMO. Also, have a look at the troubleshooting documentation here.

But I still think it would be better if you tried to do the same locally (i.e. fixing leaks) if possible.

So, I think I need write debug statements that can tell me current memory usage.

That most likely won't help you much since the garbage collector makes it somewhat hard to find memory leaks by just looking at the counts (you don't really know when the gc runs and what it actually collects, it sometimes doesn't collect everything that is collectable). So you might need to make some memory snapshots and analyse them, i.e. see which objects (or which types of objects) are not collected and thus more and more instances are created.

For this, take a look at the suggested tools (JVisualVM, JConsole).

If you still want to get memory usage information from inside your program, try the classes in the java.lang.management package;

So, I think I need write debug statements that can tell me current memory usage.

I think you are like me who prefers to profile in code instead of using an external profiling tool like JVisualVM or JConsole.

You can use a tool called MemorySampler (written by me) from CoralBits that will tell you exactly in what line of your code memory is being allocated. Below an example:

ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();
MemorySampler.start();
for(int i = 0; i < strings.length; i++) queue.offer(strings[i]);
for(int i = 0; i < strings.length; i++) queue.poll();
MemorySampler.end();
if (MemorySampler.wasMemoryAllocated()) MemorySampler.printSituation();

Gives you the following output:

Memory allocated on last pass: 24576
Memory allocated total: 24576

Stack Trace:
    java.util.concurrent.ConcurrentLinkedQueue.offer(ConcurrentLinkedQueue.java:327)
    TestGC.main(TestGC2.java:25)

Now if you go to line 327 of the ConcurrentLinkedQueue source code, you will see that it allocates a Node instance there.

Disclaimer: I am one of the developers of CoralBits.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top