Java JAI image-io jpeg2000 Memory Leak fix

One of our customers sent in a support request regarding a memory leak which was assigned to me to investigate.  It actually turned out to be rather an interesting problem and provided a fix for a bug in Sun’s own code so read on for the full details and the patched jar.

To hunt down the bug, I used the excellent JProfiler to see if it would give me a clue as to what was going on. Here is a screenshot.

 

JProfilier Screenshot

It turned out that the leak was actually in one of Sun’s own JAI classes, which have not seen much development in recent years. The jpeg2000 image reader seemed to be holding on to some resources even when the reference to the J2KImageReader instance had been released in our code.  In the screenshot you might be able to see there is 670 odd kilobytes and just over 15 thousand instances still referenced.  I looked at the reference graph in JProfilier for some of the instances and ended going round in circles!

I decided that I would have to look at the jai-imageio code to see if there was something to be done.  At this point I also realised that some of our JAI links where broken and that JAI seems to be pretty much forgotten about.

After having a look at the JAI image-io code I decided to use a pretty straight forward strategy to release the memory: set some object references to null somewhere along the line!  The J2KImageReader class seemed to be the place to start.  While having a look I realised that the J2KImageReader class did not implement a required dispose method.  When we called dispose it was just calling the super implementation of dispose in the ImageReader class.  This is an empty method with a comment saying that subclasses must implement their own dispose method.  I created a dispose method, nulled out J2KImageReaders private object members, rebuilt the image-io jar and ta-da!

JProfilier screenshotNo more memory leak!  Which was pretty cool.  The next part was a bit more difficult: commiting my change back to the jai-image-io repository, I faffed around for too long trying to see if this is still possible.  In the end I gave up!  I heard a rumour that the guy administrating the code does not work for Sun/Oracle any more, but if you have had any success comitting your changes to some of the old projects hosted on java-net then please drop me a line.

Anyway, if you are having the same problems with JAI, memory leaks and jpeg2000, we have since built our own image library which includes a high speed JPEG2000 decoder and does not use JAI.

And if you work for Oracle, can you tell me where to send the patch?

Related Posts:

The following two tabs change content below.

Daniel

Developer at IDR Solutions
When not delving into obscure PDF or Java bugs, Daniel is exploring the new features in JavaFX.
Daniel

About Daniel

When not delving into obscure PDF or Java bugs, Daniel is exploring the new features in JavaFX.

19 thoughts on “Java JAI image-io jpeg2000 Memory Leak fix

  1. sean

    You could try submitting a bug + patch to: http://java.net/jira/browse/JAI_IMAGEIO_CORE

  2. Daniel

    Cheers Sean, I’ll give it a go.

  3. Guy Mac

    It still has problems, I think in our case because our JP2s have a tile size equal to the image size and it must try to read in the entire tile even you set a small source region, and quickly runs out of (gigs of heap) memory.

    java.lang.OutOfMemoryError: Java heap space
    at jj2000.j2k.image.DataBlkInt.(Unknown Source)
    at jj2000.j2k.wavelet.synthesis.InvWTFull.getInternCompData(Unknown Source)
    at jj2000.j2k.image.ImgDataConverter.getData(Unknown Source)
    at jj2000.j2k.image.ImgDataConverter.getInternCompData(Unknown Source)
    at jj2000.j2k.image.invcomptransf.InvCompTransf.invRCT(Unknown Source)
    at jj2000.j2k.image.invcomptransf.InvCompTransf.getInternCompData(Unknown Source)
    at com.sun.media.imageioimpl.plugins.jpeg2000.J2KReadState.readSubsampledRaster(Unknown Source)
    at com.sun.media.imageioimpl.plugins.jpeg2000.J2KReadState.readBufferedImage(Unknown Source)
    at com.sun.media.imageioimpl.plugins.jpeg2000.J2KImageReader.read(Unknown Source)

  4. If the image is huge it will not fix that – it just frees the memory used afterwards.

  5. What is the license for this jar? I can’t find any information.
    Also, does the original jai-imageio’s license let you distribute a modified copy?

  6. Best link we could find is http://kenai.com/projects/volumeviewer/sources/source-code-repository/content/lib/jai-imageio/LICENSE-codecLibJIIO.txt

    I have emailed Oracle (we sent them the code fix) and spoke to the persion in charge at Javaone but still waiting for a response.

  7. Hi,

    Just posted a message in the “What’s happening with JAI”-thread, before I saw this post.

    It seems there are several parties interested in the same thing. As I stated in my previous post, I have working code that could be used as a starting point for a replacement. If someone would join in on the effort, that would be nice too. But right now, my main concern is, can (modified portions of) the jj2000 or JAI ImageIO be redistributed under a BSD license? Don’t want to make it a wasted effort.

    Thanks,


    Harald K

  8. It would really help if Oracle would make clear what they are up to (or if they have just abandoned it all).

  9. For what it’s worth, I posted a follow-up in the JAI ImageIO forum on java.net too, but the “Is JAI maintained?” thread has been unanswered since June 14th…

    .k

    • I went and asked them at Javaone. I’ll try emailing again?

  10. Yes, please do. Thanks. I emailed admins at jai.java.net last week, but I’m not really holding my breath…

    .k

  11. Guillaume

    Hi, do we have a happy end for this story?
    I face the same issue and I do need to fix it, because I have a soft which need the read thousands of images.

    • Not really. We have patched the code to fix the specific issues we had.

      There are several companies who might or do have 3rd party libraries. If you are looking for a commercial solution for JPEG and JPEG2000, I would recommend speaking to Accusoft – I visited them last week and they know their JPEGs very well.

      • Guillaume

        I have to read various type of images. Recently I had to read thousands of png/tif and the memory leak occurred.
        For png I can use imageio instead of JAI, but not for the tiff :@
        I hoped it would have been fixed since 🙁

        • I believe the memory leak was JPEG 2000-specific?

          FWIW I’ve created a BSD-licensed TIFF plugin that can be used with ImageIO directly, no need for JAI. Supports most baseline/common TIFFs.

          PS: Haven’t heard anything form Oracle on JAI despite quite a few attempts/approaches, so I’ve pretty much given up.

          .k

          • Guillaume

            It doesn’t appear to be jpeg specific 🙁
            I never use jpeg because I work on image processing (therefore the jpeg compression screws everything).

            Thank you very much for this link (didn’t know anything about it), it seems really easy to install/use!
            I am gonna try it NOW!

  12. Thanks for the link. I will pester Oracle again when I am at JavaOne.

  13. Sudharsanam

    Hi All,
    I am facing memory leak issue on decompression of Jpeg2000 images using Jai Image IO library.
    Can anyone please suggest fix for that issue? or anyone have the jai-imageio.jar file with the fixes?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>