Quantcast

Memory Leak for byte[] ???

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Memory Leak for byte[] ???

crivera
Hi guys

So i have an application that allows you to upload documents and images and saves these as byte[] in the database.

(I created an minimal example project that you can download as zip here and import into STS http://dl.dropbox.com/u/2342474/byteMemoryLeak.zip or here byteMemoryLeak.zip... all you have todo is go to the datasource.groovy and change your db settings)

So the domain object looks something like this:

class Test {

        byte[] data
       
    static constraints = {
                data nullable: false, maxSize: 1024*1024*40
    }
}

and the controller and views are all generated directly with the generate-all command... nothing changed here...

so now when we start the project we go to the test controller... hit create new... upload a document ... use something thats like 5 - 10 mb... and hit create...

i expect the memory usage to go up while the save() method is execute and then when the show method is called too... but once those are finished loading GC should pick up those objects and throw them away since they are currently not needed... now i used Your Kit Java Profiler to check the memory usage and i can see that there are 3 reference of my byte[] which have weak reference or are unreachable... why is that? shouldnt they have been removed right when the show() method or save() method complete?

here a screenshot:

do i have to make special settings for tomcat to run the gc more often???

i am very confused about this and it actually causes a problem in the application that i have in testing right now cause people are uploading a lot of documents to it and the heap memory just gets fuller and fuller and gets almost never cleaned so that i get at some point an out of memory exception... the same actually happens also in the list() method that it loads all the objects and now actually for each object the byte[] is loaded and now in memory and doesnt get cleaned up...

maybe i am just missing something or doing something wrong... any help would be greatly appreciated...

Thanks
Chris
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Memory Leak for byte[] ???

crivera
no one has ever seen this problem?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Memory Leak for byte[] ???

ideasculptor


On Fri, Apr 27, 2012 at 7:52 AM, crivera <[hidden email]> wrote:
no one has ever seen this problem?


While it does sound like you have a memory leak, I don't believe you've actually found it yet.  Unreachable references and weak references are both eligible for garbage collection so they don't actually present as memory leaks.  You'll need to do more exploring with yourkit to determine where you are leaking memory.



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Memory Leak for byte[] ???

crivera
But it seems like they don’t get collected for a very long time… maybe its some tuning for the GC that is necessary?

I actually added a cron job right now that calls Sytem.gc() every 5 min manually and that seemed to have resolve the problem with my memory issues… where before it could have gone up to 4GB (and run out of memory) it now never goes over 300 MB…

So maybe its just some GC tuning…

Chris
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Memory Leak for byte[] ???

Dean Del Ponte-2
In reply to this post by ideasculptor
We have an application in production that stores thousands of images and documents in the database, each reference as a byte[] object.

No memory leaks or problem here.

We were careful to design our domain classes so that the byte[] object would only be loaded when requested, not be default.

This allows us to work with large lists of images (MyImage below) without having the binary data loaded into memory.

For example:

class MyImage {
    String name
    String extension
    MyBinaryImage image
}

MyBinaryImage {
     byte[] image
}

- Dean Del Ponte

On Fri, Apr 27, 2012 at 12:18 PM, Samuel Gendler <[hidden email]> wrote:


On Fri, Apr 27, 2012 at 7:52 AM, crivera <[hidden email]> wrote:
no one has ever seen this problem?


While it does sound like you have a memory leak, I don't believe you've actually found it yet.  Unreachable references and weak references are both eligible for garbage collection so they don't actually present as memory leaks.  You'll need to do more exploring with yourkit to determine where you are leaking memory.




Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Memory Leak for byte[] ???

crivera
This post was updated on .
Dean Del Ponte-2 wrote
We have an application in production that stores thousands of images and
documents in the database, each reference as a byte[] object.

No memory leaks or problem here.

We were careful to design our domain classes so that the byte[] object
would only be loaded when requested, not be default.

This allows us to work with large lists of images (MyImage below) without
having the binary data loaded into memory.

For example:

class MyImage {
    String name
    String extension
    MyBinaryImage image
}

MyBinaryImage {
     byte[] image
}

- Dean Del Ponte

On Fri, Apr 27, 2012 at 12:18 PM, Samuel Gendler
<[hidden email]>wrote:
well at some point you have to load the binary image too to actually display it ... have you ever checked the with a profiler if that byte[] gets cleaned up? thats exactly what i am not experiencing... the byte[] stays there for a looooooooong time

i added the same structure in my application so that loading the byte[] only happens when it is absolutely necessary... but at some point i do have to load the data but then it gets never garbage collected for some reason...

and there are no hard references... so i only see weak and unreachable references that dont get cleaned up...

chris
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Memory Leak for byte[] ???

ideasculptor
In reply to this post by crivera


On Fri, Apr 27, 2012 at 10:23 AM, crivera <[hidden email]> wrote:
But it seems like they don’t get collected for a very long time… maybe its
some tuning for the GC that is necessary?

Clearly, but it seems like something more than just GC tuning.  Manually running System.gc() is not a long term solution.  But you really shouldn't be getting out of memory errors if you have memory allocated which is eligible for GC, unless it is allocating so quickly that GC simply cannot keep up.  But you haven't provided us with any information about your actual environment.  What jvm are you running? What options are you running it with, especially with regard to memory allocation?  What app server/servlet container is your app running in?  Do you see the problem in multiple servlet containers or just tomcat? What OS?  How much traffic is necessary to see the problem? 

And it may not be a garbage collection tuning problem at all.  You might have a very real memory leak that manually running the collector is now able to delay long enough that it appears to be fixed.  But, based on the 'evidence' you provided, there is no indication that the leak is the byte[] buffer in your domain object.  

That said, if you have the default memory allocation for tomcat in sun's jvm and you are allocating 8MB buffers, I don't think it is a surprise that you are getting out of memory errors with even relatively light traffic, since I believe the default max heap size really isn't very large at all.  I think it defaults to only 256MB, with some significant amount of that being taken up by the rest of your grails application and tomcat, leaving relatively little memory for large byte[] buffers.  From your screenshot, it looks like you've got 142MB allocated after processing just one request.  If you've only got 256MB of memory available, you can see why you might run out of memory more quickly than the GC can keep up.

--sam

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Memory Leak for byte[] ???

crivera
I am running on a windows server 2008 with Tomcat 7 and Java 7.

all the tomcat and java settings are default except Xms=512MB and Xmx=4g (so there is definitely enough ... the screenshot is from the sample application and is trying to demonstrate the fact that the GC is not collecting the byte[] )...

give it a try for yourself... start the application i provided... start the profiler ... upload a couple of documents... the upload will be fine... now continue looking at the heap memory... it will rise and rise as you upload documents ... it will clean some parts of it... but it still will keep rising and rising... and even if you dont do anything the memory wont go down...

 
Loading...