Why display .GIF image to constantly increase memory size?

I am showing a simple code example. I showed a gif image in Jlabel . When the program starts, the TASK manager shows that the memory is constantly increasing. Why is this happening?

Edited by:

try this code, please ... on the show glass button, the glass panel is displayed with a gif image and a hidden glass button in it, and with this memory the increase will begin. When you click the "Hide glass" button, the glass panel will be hidden, and the increase in memory will stop.

@mKorbel: I debugged it, the constructor will be called once, so reinitializing the JFrame does not turn on: setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

 public class circle extends JFrame { public ImageIcon pic; final JPanel glass; public JButton glass_show; public JButton hide_glass; public circle() { super("Hi shamansdsdsd"); setSize(500, 300); // Image icon initialize once : pic = new ImageIcon("images/loadinag.gif"); glass_show = new JButton("Show Glass panel"); this.add(glass_show); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); glass = (JPanel) this.getGlassPane(); hide_glass = new JButton("Hide Glass panel"); glass.add(hide_glass); glass.add(new JLabel(pic)); glass.setOpaque(false); } public void initialize_listeners(){ glass_show.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent A) { glass.setVisible(true); } }); hide_glass.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent A) { glass.setVisible(false); } }); } public static void main(String[] args) { circle mFrame = new circle(); mFrame.initialize_listeners(); mFrame.setVisible(true); } 

}

+4
source share
2 answers

There is a bug in Java with animated GIFs. No memory increase with other images.

Edit

The following example runs without memory leak; but you need the Eclipse SWT library from the Eclipse website

 import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.ImageLoader; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Shell; public class GIFExample { static Display display; static Shell shell; static GC shellGC; static Color shellBackground; static ImageLoader loader; static ImageData[] imageDataArray; static Thread animateThread; static Image image; static final boolean useGIFBackground = false; public static void main(String[] args) { display = new Display(); shell = new Shell(display); shell.setSize(300, 300); shell.open(); shellGC = new GC(shell); shellBackground = shell.getBackground(); FileDialog dialog = new FileDialog(shell); dialog.setFilterExtensions(new String[] {"*.gif"}); String fileName = dialog.open(); if (fileName != null) { loader = new ImageLoader(); try { imageDataArray = loader.load(fileName); if (imageDataArray.length > 1) { animateThread = new Thread("Animation") { @Override public void run() { /* Create an off-screen image to draw on, and fill it with the shell background. */ Image offScreenImage = new Image(display, loader.logicalScreenWidth, loader.logicalScreenHeight); GC offScreenImageGC = new GC(offScreenImage); offScreenImageGC.setBackground(shellBackground); offScreenImageGC.fillRectangle(0, 0, loader.logicalScreenWidth, loader.logicalScreenHeight); try { /* Create the first image and draw it on the off-screen image. */ int imageDataIndex = 0; ImageData imageData = imageDataArray[imageDataIndex]; if (image != null && !image.isDisposed()) image.dispose(); image = new Image(display, imageData); offScreenImageGC.drawImage( image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, imageData.width, imageData.height); /* Now loop through the images, creating and drawing each one * on the off-screen image before drawing it on the shell. */ int repeatCount = loader.repeatCount; while (loader.repeatCount == 0 || repeatCount > 0) { switch (imageData.disposalMethod) { case SWT.DM_FILL_BACKGROUND: /* Fill with the background color before drawing. */ Color bgColor = null; if (useGIFBackground && loader.backgroundPixel != -1) { bgColor = new Color(display, imageData.palette.getRGB(loader.backgroundPixel)); } offScreenImageGC.setBackground(bgColor != null ? bgColor : shellBackground); offScreenImageGC.fillRectangle(imageData.x, imageData.y, imageData.width, imageData.height); if (bgColor != null) bgColor.dispose(); break; case SWT.DM_FILL_PREVIOUS: /* Restore the previous image before drawing. */ offScreenImageGC.drawImage( image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, imageData.width, imageData.height); break; } imageDataIndex = (imageDataIndex + 1) % imageDataArray.length; imageData = imageDataArray[imageDataIndex]; image.dispose(); image = new Image(display, imageData); offScreenImageGC.drawImage( image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, imageData.width, imageData.height); /* Draw the off-screen image to the shell. */ shellGC.drawImage(offScreenImage, 0, 0); /* Sleep for the specified delay time (adding commonly-used slow-down fudge factors). */ try { int ms = imageData.delayTime * 10; if (ms < 20) ms += 30; if (ms < 30) ms += 10; Thread.sleep(ms); } catch (InterruptedException e) { } /* If we have just drawn the last image, decrement the repeat count and start again. */ if (imageDataIndex == imageDataArray.length - 1) repeatCount--; } } catch (SWTException ex) { System.out.println("There was an error animating the GIF"); } finally { if (offScreenImage != null && !offScreenImage.isDisposed()) offScreenImage.dispose(); if (offScreenImageGC != null && !offScreenImageGC.isDisposed()) offScreenImageGC.dispose(); if (image != null && !image.isDisposed()) image.dispose(); } } }; animateThread.setDaemon(true); animateThread.start(); } } catch (SWTException ex) { System.out.println("There was an error loading the GIF"); } } while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } } 

Source code

+3
source

there are two areas

1) you forgot to declare setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); , then the current JVM instance is still in (RAM), until the PC restarts or power off

2) Perhaps you are creating a new JFrame for each image on the fly

+1
source

Source: https://habr.com/ru/post/1383411/


All Articles