If you’re a Resin Pro user, you might have noticed that since Resin 3.1, we’ve had a heap dump available in the /resin-admin administration application. It’s a great tool to help you figure out which objects are taking up the most memory, but you might have trouble parsing the data the first time you see it. I’ll go over the heap dump here to make it a little easier…
Notice the little “dump heap” button? You’ll need to press it each time you want a new heap dump. They can be expensive, so we decided not to automate it and peg your CPU… This screenshot is from Resin 3.1. Resin 3.2 also has a heap dump, but it’s toward the bottom of the “Memory” tab page, underneath a bunch of pretty graphs.
Once you have a heap dump as above, you’ll see 6 columns. I’ll address them from right-to-left:
- class - The class whose instances this row describes.
- count - How many instances there are of this class.
- desc - Short for “descendants”. This describes the total memory taken up by objects reachable from the instances of this class.
- self - How much memory instances of this class take up, not counting any reachable objects
- self+desc - Total amount of memory taken up by both the instances and the reachable objects from the instances of this class.
- rank - A simple formulation of how much heap this class’s instances take up on the heap relative to the class using the most memory. (rank=self+desc/max(self+desc))
Let’s take a look at the first couple of entries in this heap dump. HashMap, HashMap$Entry, and String are at the top. This is probably going to be similar in most systems. The HashMap is the top row, so it has rank 1.0. The top row will always have rank 1.0. There are 4954 HashMap instances in the system and in total, they consume 12.459 megabytes in the heap. The HashMaps themselves only take up 0.189 megabytes, but the descendants take up 12.270 megabytes. This is what you would expect with a collection-type (lower case ‘c’) data structure like a HashMap. Expect similar results from sets, lists, etc.
Now let’s see what happens when we run an application that uses a lot of data. I created an object:
And created an instance in a webapp using Resin IoC within my resin-web.xml:
Now let’s do another heap dump:
We can see that the largest class using memory on the heap is now byte. That’s because of our Foo object creating a 16M buffer. The next class in the list is example.Foo$BeanProxy. The BeanProxy at the end indicates that this object was created by Resin IoC. Thus in this dramatic example, we can see direct results of allocating objects.
You might have memory leaks in your application that can be discovered by the heap dump. Early on, they may not appear at the top of the list like our Foo example did, but you might want to keep track of classes that are moving up the list quickly and taking up more memory than they should.
If you found this useful, you may want to check out our Resin administration training course, which will contain more tips like this to help you better understand Resin.