0

I was testing performance of Guava cache by loading 5000 objects in cache using 50 threads using ExecutorService. I wanted to see the heap occupied by the cached objects.

It looked as though the cached objects were eating up 25MB.

Later, I put a Thread.sleep on the main thread to sleep the application for 10 minutes, so that I could sample the memory etc.

Surprisingly, even when the application is on sleep, it generates 20MB of garbage every 4 minutes. Since there is a GC operation every 4 minutes, I am seeing a Sawtooth wave in the used heap graph. enter image description here

Why does java generate 5MB of garbage per minute in an idle application?

UPDATE: I ran just a main method with only a call to Thread.sleep for 10 minutes.

Memory allocation is 4 MB per minute. enter image description here

Below is the memory sampler screenshot. Looks like only the RMI TCP connection thread which is causing all the activity. enter image description here

Is it just the fact that we are observing with VisualVM causing all that activity? Or is it regular jvm activity?

Teddy
  • 4,009
  • 2
  • 33
  • 55
  • 1
    What are the 9 daemon threads doing while the main thread is asleep? – Chris Martin Jan 02 '15 at 09:33
  • 1
    And more to the point, best stop caring about such details. Some thread, somewhere, is runnig some scheduled code or similar, and creating 80 KB of garbage per second. It could be the very thread which communicates with VisualVM. This will have no impact on your application's overall behavior. – Marko Topolnik Jan 02 '15 at 09:35
  • ExecutorService 50 threads completed at 3:28pm and were terminated. JVM itself is having 10 daemon threads. Application has only 1 active non-daemon thread. That one thread is asleep for ~10 minutes. – Teddy Jan 02 '15 at 09:35
  • @MarkoTopolnik I agree with you. I can ignore it as it is not creating any problem. It is just surprising that my 5000-object-pair-cache takes only 5MB and JVM is generating 5MB garbage per minute. – Teddy Jan 02 '15 at 09:38
  • There's a huge difference between retained memory and garbage. Short-lived objects are very cheap to collect and many Java idioms naturally involve such objects. – Marko Topolnik Jan 02 '15 at 09:45

2 Answers2

1

You were using VisualVM to monitor your application. VisualVM is using JMX/MBeans to get monitoring information. JMX is using RMI as transport layer. VisualVM is polling MBeans regularly which translates to calling service running on your JVM via RMI.

4 MiB per minute sounds to be reasonable number to blame VisualVM for.

I suggest you to monitor you process with SJK ttop command. It displays memory allocation rate per thread, so you can verify if all garbage could be attributed to RMI threads or any of your application thread do some littering.

Alexey Ragozin
  • 8,081
  • 1
  • 23
  • 23
0

As the bottom line: no one can answer such question without profiling your application. What you need is to take a memory snapshot in visual VM and check what classes are taking large amount of memory. Also it helps to sort the object counts and see which objects have most instance count change before and after the GC.

For a quick glimipse, since you have 11 threads shown in your pic, at least you have the node objects for the Runnable objects submitted to your ExecutorService, which most of the current Java libs and packges would opt.

Alex Suo
  • 2,977
  • 1
  • 14
  • 22
  • My executor service finished and terminated all 50 threads at 3:28pm. It is a test application... there is no other processing being done. Only a single application thread which is on sleep for 10 minutes and some 10 daemon threads started by JVM probably. – Teddy Jan 02 '15 at 09:43
  • @Teddy No one can answer you without profiling, which can only be done yourself... – Alex Suo Jan 02 '15 at 09:44
  • I ran the memory sampler and attached the screenshot – Teddy Jan 02 '15 at 10:48
  • 1
    @Teddy - and the attached screenshot answers your question. – Stephen C Jan 04 '15 at 07:23