user4179961
user4179961

Reputation:

Java heap growth

I'm developing a desktop java application and am trying to optimize memory usage at runtime, using Java visualVM.

The thing is that I've noticed that my used heap is growing about 1mb/s and I'm trying to find out what's causing it. This is what it looks like:

enter image description here

First of all, I've noticed that the JVM seems to be allocating quite a lot of memory at runtime by itself. I've tried to make a dummy program that just sleeps and the increase in used heap seemed to be about 0.2Mb/s.

However, My application obviously allocates more. And I know I'm creating quite a lot of objects at runtime, but it shouldn't be close to MBs/s, more like bytes/second.

So, I've made a few dumps and compared them. Here's the first, when a fresh GC has been invoked:

enter image description here

And here's the other, where the used heap has grown ~100MB:

enter image description here

Here's the comparison:

enter image description here

Now, what's confusing me is that I can't find any trace of the additional 100 mb in the two dumps.

Total bytes are the same. Classes are the same. Instances are about the same. And the comparison gives me no hints. The dumps, however, confirms that I'm only allocating a handful of classes/s. So what gives?

Update 1: Using the eclipse memory manager:

enter image description here

(The suspects aren't culprits). And I'd like to stress that visualVM showed me a 100MB difference in used heap at the time of the dumps. My in-application

print("Used Mbs: " + (r.totalMemory() - r.freeMemory())/mb);

Also confirmed this. ('r' is a Runtime instance)

Upvotes: 1

Views: 1374

Answers (2)

user4179961
user4179961

Reputation:

I found this neat function in visualVM - monitoring.

So, I've been monitoring this:

    public static void main(String[] args) {

    while (true){
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


}

And it seems that the JVM is allocating loads of chars[], Object[], byte[], int[], TreeMap$Entry and such. I've been watching my application as well and it seems to follow the same pattern, only larger volumes of it. So, I'm going to rule this out as all Oracles' fault. That the JVM overhead grows along with the application. Unless someone can come up with a better idea?

Upvotes: 1

duffymo
duffymo

Reputation: 308763

I don't think you have a problem.

You need to learn about the JVM memory model and generations.

The sawtooth pattern for young generation says so. That's the garbage collector doing its job.

The permanent stuff you see that grows is perm gen (or it was for JDK 7 and earlier). That's where Strings, .class byte code, etc. live.

Upvotes: 2

Related Questions