File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Performance and the fly likes Live Bytes for an object Instance in JVisualVM increase on every operation Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Java » Performance
Bookmark "Live Bytes for an object Instance in JVisualVM increase on every operation" Watch "Live Bytes for an object Instance in JVisualVM increase on every operation" New topic
Author

Live Bytes for an object Instance in JVisualVM increase on every operation

Jack Numen
Ranch Hand

Joined: Nov 09, 2011
Posts: 42

Hi,
While monitoring in JVisualVM ....

Whenever i perform any operation in my application Live Bytes of a particular Instance of a class increases by 1000.

Although i perform the same operation everytime it always increases by 100 or 1000.

Is this a memory leak or does these instances increase everytime we perform an operation.

Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2447
    
  28

Whenever you allocate an object, the object will be allocated on the heap. This will make the number of bytes allocated go up. This is perfectly acceptable.

When you release all references to the object, the object will be eligible for Garbage collection. When GC runs, it will scan the heap for objects eligible for GC, and frees the memory on the heap that was allocated to the objects. So, it is expected that the number of bytes allocated on the heap will not go down as soon as the object is released. Instead, it will go down at the next collection. This is entirely acceptable

Generally, GC is kind of lazy, and it runs only when it absolutely needs to. So, if you run some operations that allocate a few objects, use them, then release them; the memory allocated for those objects won;t be released right after the operation is done. Instead it will be released at the next GC. If you are monitoring memory, you should wait for GC to run.
fred rosenberger
lowercase baba
Bartender

Joined: Oct 02, 2003
Posts: 11494
    
  16

I don't know the answer to this question, but is the GC REQUIRED to collect all available/elligible objects?

I would think that if I still have 90% of my memory available, the GC would just say "meh - why bother?"

I could be wrong. But i'm not sure I would rely on the fact of all possible memory is reclaimed on every run.


There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors
Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2447
    
  28

Usually, GC doesn't run until it absolutely has to. That's what I mean "GC is lazy". The heap is divided into several areas. Generally GC doesn;t run until one of those spaces are full. Also, when one the younger generation area is full, it will run a minor collection rather than a major collection. It will run a major collection when the old gen is full.

Usually, if you have an application that is constantly running and churning through objects, you will see the heap usage step up gradually till it almost runs to 100%. At this point, GC runs a major collection, and the memory usage drops down. GC goes to sleep, and the whole cycle repeats itself. This is why in many applications that are constantly under load (and churning objects), the memory usage graph typically looks like a sawtooth. A sawtooth is extremely normal. Most people freak out when they see the sawtooth "Help my memory is not being released imediately!!"

WHat matters is that the bottom of the sawtooth should stay level, or at some point come down to where it started with . Your "real" memory usage are the bottom troughs of the saw tooth. ANother thing that matters is how many times the GC runs.. or visually speaking, how many teeth in your memory plot. It indicates the number of times the GC has to run, which takes considerable resources. If you have lots of teeth, it means you are using lot of temporary objects.
Jack Numen
Ranch Hand

Joined: Nov 09, 2011
Posts: 42

Hi,
I understand the concept of GC and creation of instances.I am actually looking into some performance issues and i came across this instance creation and memory allocation for the same.

Let us suppose that for a single operation around 1MB of data is allocated for creating such instances and practically speaking this happens in my system.

As you go on operating the same instance is created over and over again.

Now if there are 30 users working at that time let us say 30MB of memory is allocated to such instances.

Let us say there is 1Gb of allocated memory and after 1-2 hours most of the memory gets full.

Now the garbage collector will look over if any of the memories are full and does GC and frees the memory.

Here please explain me whether the increase in memory will cause any performance degrade as the Search for a single instance over a large heap will be more time consuming.

If this lead to Performance degrade what are the possible ways of fixing this.

Best Regards,
Jack
Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2447
    
  28

Are you holding a reference to the instance? If you are not holding a reference to the instance, then it will get garbage collected. You don't have memory leak.

If you are holding on the reference to the instance, the short answer is yes, there will be performance degradation because GC will have to run more often. To understand how performance will degrade, you need to go through a very lengthy explanation:

Let's say each user request does the same operation. That operation allocates 10MB of memory on the heap. Let's assume that there is no memory leak. Let's assume that this operation takes 1s. Also assume that you have 1GB of memory. You are constantly doing the same operation over and over again

At 1s, the memory used on the heap will be 10MB
At 2s, 20MB
At 3s, 30MB

...

At 100s, 1GB

Now GC runs.. Let's assume that GC needs 100ms to run. While GC is running, nothing else is happenning. So, every 100s, your system pause for 0.1s. This means the overhead of GC is

Overhead = 0.1/100 = 0.1%

Every 100s, the system will pause for 0.1s to do GC, and it will keep doing that forever. It's not a big deal because 0.1% is nothing
---------------------------------------------------

Now, let's see, what happens f there is a memory leak. Let's assume that you operation uses the same 10MB of memory, but releases only 9MB. 1 MB is a leak.

At 1s, the memory used on the heap will be 10MB
At 2s, 20MB
At 3s, 30MB

...

At 100s, 1GB

Now, GC runs... but it releases only 900MB. Because each operation held on to 1MB.. and there were 100 operations, 100MB on the heap is not released

In the first cycle, the overhead is still 0.1%. There is a memory leak, but you don't notice the perfomance degradation.. yet

So, at 101s, the memory used = 100MB (the memory that was leaked) + 10MB (the memory that was used) = 110MB
102 s, 120MB
.
.
.
190s, 1GB

Wait a minute.. what happenned here? How did it get full in 90s. It got full in 90s because you started with 100Mb not 0MB. So, again it takes 0.1s to run GC.. So, second iteration overhead = 0.1/90 = 0.11%. Also, the amount of memory used in heap is 200MB

So, third iteration
201s, 210MB
202 s, 120MB
.
.
.
280s, 1GB

Overhead = 0.1/80 = 0.14%


Actually, if you follow this calculation, you will find that at the end of 10 iterations, the GC overhead grows to -.23%. At the end of 50 iterations, it's 14.14%, and at the end of 67 iterations, it's 95%
Jack Numen
Ranch Hand

Joined: Nov 09, 2011
Posts: 42

Thank you Jay,

That was indeed a clear explanation.


Now the detective is off to find the leak
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Live Bytes for an object Instance in JVisualVM increase on every operation