Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

track down allocations of int[]

Tags:

java

debugging

When viewing my remote application in JVisualVM over JMX, I see a saw-tooth of memory usage while idle:

enter image description here

Taking a heap dump and analysing it with JVisualVM, I see a large chunk of memory is in a few big int[] arrays which have no references and by comparing heap dumps I can see that it seems to be these that are taking the memory and being reclaimed by a GC periodically.

I am curious to track these down since it piqued my interest that my own code never knowingly allocates any int[] arrays.

I do use a lot of libs like netty so the culprit could be elsewhere. I do have other servers with much the same mix of frameworks but don't see this sawtooth there.

How can I discover who is allocating them?

like image 644
Will Avatar asked Jun 17 '13 10:06

Will


2 Answers

Take a heapdump and find out what objects are holding them. Once you know what objects are holding the arrays you should have an easy time idea figuring out what is allocating them.

It doesn't answer your question, but my question is:

Why do you care?

You've told the jvm garbage collector (GC) it can use up to 1GB of memory. Java is using less than 250M.

The GC tries to be smart about when it garbage collects and also how hard it works at garbage collection. In your graph, there is no demand for memory. The jvm isn't anywhere near that 1GB limit you set. I see no reason the GC should try very hard at all. Not sure why you would care either.

Its a good thing for the garbage collector to be lazy. The less the GC works, the more resources there are available for your application.

Have you tried triggering GC via the JVisualVM "Perform GC" button? That button should trigger a "stop the world" garbage collection operation. Try it when the graph is in the middle of one of those saw tooth ramp ups - I predict that the usage will drop to the base of the saw tooth or below. If it does, that proves that the memory saw tooth is just garbage accumulation and GC is doing the right thing.

Here is an screenshot of memory usage for a java swing application I use: enter image description here

Notice the sawtooth pattern.

You said you are worried about int[]. When I start the memory profiler and have it profile everything I can see the allocations of int[]

enter image description here

Basically all allocations come from an ObjectOutputStream$HandleTable.growEntries method. It looks like the thread the allocations were made on was spun up to handle a network message.
I suspect its caused by jmx itself. Possibly by rmi (do you use rmi?). Or the debugger (do you have a debugger connected?).

like image 96
Ryan Avatar answered Nov 03 '22 02:11

Ryan


I just thought I'd add to this question that the sawtooth pattern is very much normal and has nothing necessarily to do with your int[] arrays. It happens because new allocations happen in the Eden-gen, and an ephemeral collection only is triggered once it has filled up, leaving the old-gen be. So as long as your program does any allocations at all, the Eden gen will fill up and then empty repeatedly. Especially, then, when you have a regular amount of allocations per unit of time, you'll see a very regular sawtooth pattern.

There are tons of articles on the web detailing how Hotspot's GC works, so there's no need for me to expand on that here. If you don't know at all how ephemeral collection works, you may want to check out Wikipedia's article on the subject (see the "Generational GC" section; "generational" and "ephemeral" are synonymous in this context).

As for the int[] arrays, however, they are a bit mysterious. I'm seeing those as well, and there's another question here on SO on the subject of them without any real answer. It's not actually normal for objects with no references to show up in a heap dump, because a heap dump normally only contains live objects (because Hotspot always performs a stop-the-world collection before actually dumping the heap). My personal guess is that they are allocated as part of some kind of internal JVM data-structure (and therefore only have references from the C++ part of Hotspot rather than from the Java heap), but that's really just a pure guess.

like image 21
Dolda2000 Avatar answered Nov 03 '22 00:11

Dolda2000