OutOfMemoryError: Java Heap Space

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • HxRLxY
    New Member
    • Sep 2008
    • 23

    OutOfMemoryError: Java Heap Space

    I have a program that shows a thumbnail of an image. If the user clicks on the thumbnail a new JFrame is opened that shows the full size image. If the image is larger than the screen, it gets scaled to the the size of the screen.

    Functionally, the program works well. However, when testing I found that after clicking the thumbnails of several images (and subsequently closing their viewing frames), I get an java.lang.OutOf MemoryError: Java heap space. I'm not really sure what to do about this. Below the code I've included a snippet of the StackTrace.

    I've been searching around, and most forums talk about increasing heap size. I don't want to have to do that. It seems like if I'm properly releasing resources, I shouldn't have the problem. All I want the program to do is: show a full size image in a new window, then return those resources when the window is closed.

    Thanks in advance for any help.

    Here is my code:

    Code:
    //==================================================================================
    //will scale a provided image to the provided size
    //==================================================================================
           public static BufferedImage scaleImage (Image image, int width, int height)
          {
             if (image == null)
             {
                return null;
             }
             else
             {
                Image temp = image.getScaledInstance (width, height, Image.SCALE_SMOOTH);
             
                BufferedImage scaledImage = new BufferedImage (
                   temp.getWidth (null), temp.getHeight (null), BufferedImage.TYPE_INT_RGB);
                
                Graphics2D g2d = (Graphics2D)scaledImage.getGraphics();
                g2d.drawImage (temp, 0, 0, null);
                g2d.dispose();
             
                return scaledImage;
             }
          }
    //==================================================================================
    //will open a full size version of an image in a new window
    //==================================================================================
           public static void showFullSizeImage (BufferedImage temp, String fileName)
          {
             final BufferedImage scaledImage;
             int width = temp.getWidth();
             int height = temp.getHeight();
             Toolkit tk = Toolkit.getDefaultToolkit();
          	
             Dimension screenDimension = tk.getScreenSize();
          	
             if (temp != null)
             {
                if (width >= height)
                {
                   if (screenDimension.getWidth() >= width)
                   {
                      scaledImage = Utility.scaleImage (
                         temp, (int)(screenDimension.getWidth()), -1);
                   }
                   else
                   {
                      scaledImage = temp;
                   }
                }
                else
                {
                   if (screenDimension.getHeight() >= height)
                   {
                      scaledImage = Utility.scaleImage (
                         temp, -1, (int)(screenDimension.getHeight()));
                   }
                   else
                   {
                      scaledImage = temp;
                   }
                }
             }
             else
             {
                scaledImage = null;
                JOptionPane pane = new JOptionPane();
                pane.showMessageDialog (null, "Could not display image");
             }
             
             if (scaledImage != null)
             {
                JFrame frame = new JFrame (Utility.parseFileName (fileName));
                frame.addWindowListener (
                       new WindowAdapter(){
                          public void windowClosed (WindowEvent e){
                            JFrame frame = (JFrame)e.getSource();
                            frame.dispose();
                         }
                      });
                
                JPanel panel = 
                    new JPanel(){
                       public void paintComponent (Graphics g){
                         g.drawImage (scaledImage, 0, 0, null);
                         g.dispose();
                      }
                   };
                panel.setPreferredSize (
                   new Dimension (scaledImage.getWidth(), scaledImage.getHeight()));
                
                frame.add (panel);
                frame.pack();
                frame.setLocationRelativeTo (null);
                frame.setVisible (true);
             }
          }
    Code:
    at java.awt.image.DataBufferInt.<init>(DataBufferInt.java:41)
    at java.awt.image.Raster.createPackedRaster(Raster.java:458)
    at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1015)
    at java.awt.image.BufferedImage.<init>(BufferedImage.java:312)
    at Utility.scaleImage(Utility.java:104)
    at Utility.showFullSizeImage(Utility.java:174)
    at DisplayPanel$2.mouseClicked(DisplayPanel.java:78)
  • JosAH
    Recognized Expert MVP
    • Mar 2007
    • 11453

    #2
    I think that final BufferedImage scaledImage reference is in your way. Create a separate class extending from a JFrame that you can construct with a BufferedImage parameter so you don't need that final reference anymore.

    When you dispose the JFrame, also flush() the image.

    kind regards,

    Jos

    Comment

    Working...