0

I have images that are downscaled as 150x150 thumbnails (original resolutions can be up to 10,000x10,000), however even after I downscale them the task manager still shows I'm using entire gigabytes of memory.

private void addImage(String path) {
    BufferedImage image = ResourceManager.loadImageFromPath(path);

    BufferedImage subImage;
    int delta = image.getHeight() - image.getWidth();
    if (delta > 0) {
        subImage = image.getSubimage(0, delta / 2, image.getWidth(), 
    image.getHeight() - delta);
    } else if (delta < 0) {
        subImage = image.getSubimage(-delta / 2, 0, image.getWidth() + delta,         
 image.getHeight());
    } else {
        subImage = image;
    }

    Resizer resizer = DefaultResizerFactory.getInstance().getResizer(new 
    Dimension(subImage.getWidth(), subImage.getHeight()), new Dimension(150, 150));
    BufferedImage scaled = new FixedSizeThumbnailMaker(150, 150, true, true)
        .imageType(BufferedImage.TYPE_INT_RGB)
        .resizer(resizer)
        .make(subImage);

    imageList.add(path);
    ImageCard card = new ImageCard(scaled, imageList.indexOf(path));
    imagesPane.add(card);

    image.flush();
    subImage.flush();
}
public static BufferedImage loadImageFromPath(String path) {
    System.out.println("Importing image: " + path);
    try {
        return ImageIO.read(new File(path).toURL());
    } catch (IOException ex) {
        System.err.println("Failed to load file: " + path);
        ex.printStackTrace();
        return null;
    }
}
  • Try adding a `system.gc()` after downsizing – ControlAltDel Mar 01 '21 at 18:49
  • @ControlAltDel Doesn't seem to do anything – Alex Hammond Mar 01 '21 at 18:53
  • A profiler would help, and information about the java version and the GC used. Not all GC are returning unused memory to the operating system. – Dorian Gray Mar 01 '21 at 18:57
  • My only guess is that somewhere in your program, you still keep a reference to that first `image` you load and the garbage collector therefore can't free it from memory, but I can't find anything in the code you've shown us... About `System.gc()`: Make sure to call it *after* the program has left the `addImage` method; otherwise the gc will think it's still in use. – cegredev Mar 01 '21 at 18:58
  • @DorianGray I'm just using standard Java 1.8, I'll download a java profiler and have a look. – Alex Hammond Mar 01 '21 at 19:03
  • What about Java 11? – Dorian Gray Mar 01 '21 at 19:04
  • @DorianGray Just ran JProfiler and 99% of memory consumption is "free size", and "used size" spikes when the images are imported but they go back down after. Not really sure what this means. – Alex Hammond Mar 01 '21 at 19:21
  • 3
    It means that the memory is not returned to the operating system, as I said above. As far as I know, that was the default in Java 8 (and even Java 11?) Try comparing it to Java 11. – Dorian Gray Mar 01 '21 at 19:25
  • @DorianGray Goes down to 200MB in Java 14 (don't have java 11 installed), much much better and pretty much kills the rest after i force GC. Thanks – Alex Hammond Mar 01 '21 at 19:35
  • 2
    Don’t handle exceptions that way. You are basically converting the `IOException` to a `NullPointerException`. – Holger Mar 02 '21 at 07:58

0 Answers0