简体   繁体   中英

java heap memory issue

My application is basically a photo browser . My approach (don't judge me, I am new to java) was to have an ArrayList filled with BufferedImages and then add the images to the JList (to the left).

This is how I get an image :

private void getFullImage() {

        BufferedImage im = null;        


        ImageReader imageReader = null;
            try {
                System.out.println("Loading "+original+"...");
                String suffix = Utils.getFileExt(original.getName(), "jpg");
                @SuppressWarnings("rawtypes")
                Iterator readers = ImageIO.getImageReadersBySuffix(suffix);
                imageReader = (ImageReader)readers.next();
                imageReader.setInput(new FileImageInputStream(original));
                im = imageReader.read(0);
                imageReader.dispose();
            } catch (Exception e)
            {
                e.printStackTrace();
            }

        this.img = im;
    }

and then, after I fetched all the data, I would add the images to my JList :

   Vector vector = new Vector();
   JPanel container = null;
   PhotoPanel pp = null;
   Photo p = null;
   for(int i=0;i<files.length;i++)
   {
        p = new Photo(files[i]);
        pp = new PhotoPanel(p);
        container = new JPanel(new BorderLayout());
        container.add(pp,BorderLayout.CENTER);
                                       container.setBorder(BorderFactory.createTitledBorder(p.getTitle()));
                                vector.addElement(container);
  }
   plist.setListData(vector);

If I have for example 10 files, the app works pretty well. The problem is when I have a lot more images to show. Then I would get an exception : Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space . So, I know my approach is a very poor one, and I am wondering how should I take and store all the images and have them to be displayed in the JList . Maybe using the cache memory? I read something about SoftReference but I don't really know how to use it. Thanks.

There are two main possible causes for the problem:


The first, and which I'm posting more as a warning than as an actual cause in your case, is that an excessive amount of data is being printed on the console with the System.out.println() .

I am unsure if it only occurs with NetBeans or all Development tools. But either way, it requires a truly absurd amount of printing for it to be triggered, and i doubt you have that many files loading.

Anyways, if your intent with the System.out.println("Loading "+original+"..."); line is for a permanent/production logging, rather than something you've put on code just temporarily for development/debug purposes, then you are better off with a proper Logger . You can read a TL;DR version of instructions in this SO answer , and you can read further, including the official documentation, through the links provided there.


The other cause, which is quite certainly your's, is that you are having too much data loaded at the same time. The solutions are to either:

  1. Scale down the images (make thumbnails), and only show the full-size version for the selected image. Please note tough, that this is a fast solution method, and is not recommended! As it might still be too much for the system to withstand.
  2. Only have the images present at visible portion of the interface loaded (or the thumbnails of said images, for a combined, best solution), and load new images (and unload the others), as the interface is navigated.

I was struggling a lot with large images (in SWT though) and those OutOfMemory and NoMoreHandles (which might happen even, if there is not enough memory) were a nightmare. I think there is no way, to keep large images or have a lot of images in memory. I agree with Andrew's comment, but just wanted to add, that depending on your requirements you could try to extend a canvas (or whatever there is in Swing) and DRAW your images directly on it, without holding those in memory (similar for PaperClips#PrintPreview). Sure, you will need to have some calculations to layout images correctly, but I think, that in this case you might overcome your problems with memory (but get some other problems:))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM