1

I am developing a swing application where i am displaying profile information along with their photo, after loading about 120 photos i get the exception java.lang.OutOfMemoryError: Java heap space I need to display around 1000+ profile informations. This is how i load my images onto the jtable

try{                
    byte[] imageAsByteArray = getImageAsByteArray("E:\\Project\\WinPak\\Database\\UserImage\\"+employee.getLink3().trim()+"-1.jpg");    
if(imageAsByteArray != null)
{

InputStream imageInputStream =new ByteArrayInputStream(imageAsByteArray);

    Image img = ImageIO.read(imageInputStream);
    ImageIcon imgIcon = new ImageIcon(img.getScaledInstance(100,100,Image.SCALE_AREA_AVERAGING));

    data[index][10] =imgIcon; // data is of type object which i use to populate the jtable
    imageInputStream.close();
}
}
catch(Exception e)
{
  e.printStackTrace();
}

public byte[] getImageAsByteArray(String url)
{
    try
    {
        InputStream is = new BufferedInputStream(new FileInputStream(url));
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();

            int nRead;
            byte[] data = new byte[16384];

            while ((nRead = is.read(data, 0, data.length)) != -1) {
                buffer.write(data, 0, nRead);
            }

            buffer.flush();
            is.close();
            return buffer.toByteArray();

    }
    catch(Exception e)
    {
        e.printStackTrace();
        return null;
    }
}

How do i overcome this problem. Is there any other way to display the information in swing?

Akhilesh
  • 11
  • 1
  • 1
    1) A quick test shows that a standard memory assigned to a JRE can hold 6000+ images of 100 x 100 pixels that also contain transparency. This indicates that either the image scaling or image loading is hanging onto memory after it was necessary to do so. 2) See [The Perils of `Image.getScaledInstance()`](https://community.oracle.com/docs/DOC-983611). 3) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). My test code was just 108 lines of code, including imports and a `main(String[])` method - an MCVE. – Andrew Thompson Jul 16 '16 at 14:36

2 Answers2

1

If you are not aware of -Xmx command line argument to Java, you should learn about that and try that as a short term workaround. See documentation here.

The larger issue, though, is whether you really need to keep all of these images in memory at the same time. For a table that is displaying images, you might want to load the image only if it is currently supposed to be displayed or in a row near to what is being displayed.

I don't see anything obviously wrong with the way that you are reading the images, but I haven't worked with I/O of images in Java much, so perhaps that could be improved too.

Evan VanderZee
  • 797
  • 6
  • 10
1

In outline,

  • Create thumbnail-sized copies of your images, as shown here and here, to make instances of ImageIcon; use a background thread, as shown here, to keep the GUI responsive.

  • In your TableModel, return ImageIcon from getColumnClass() for the image column; the default renderer will display it automatically.

  • Use an adjacent component or popup to display the full size image on demand.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045