Java 为什么显示.GIF图像会不断增加内存?
我正在展示简单的代码示例。我在Java 为什么显示.GIF图像会不断增加内存?,java,swing,memory-management,gif,jlabel,Java,Swing,Memory Management,Gif,Jlabel,我正在展示简单的代码示例。我在Jlabel中显示了一个gif图像。运行程序时,任务管理器显示内存在不断增加。为什么会这样 编辑: 请尝试此代码。。。在“显示玻璃”按钮上,玻璃面板上显示gif图像和一个隐藏玻璃按钮,内存将开始增加。单击“隐藏玻璃”按钮,玻璃面板将被隐藏,内存增加将停止 @mKorbel:我已经调试过了,构造函数将被调用一次,因此没有重新初始化JFrame,还包括:setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) }有两个方面 1) 您忘
Jlabel
中显示了一个gif图像。运行程序时,任务管理器显示内存在不断增加。为什么会这样
编辑:
请尝试此代码。。。在“显示玻璃”按钮上,玻璃面板上显示gif图像和一个隐藏玻璃按钮,内存将开始增加。单击“隐藏玻璃”按钮,玻璃面板将被隐藏,内存增加将停止
@mKorbel:我已经调试过了,构造函数将被调用一次,因此没有重新初始化JFrame,还包括:setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
}有两个方面
1) 您忘记声明setDefaultCloseOperation(JFrame.EXIT\u ON\u CLOSE)代码>则当前JVM实例仍在(本机操作系统)RAM中,直到PC重新启动或关机
2) 可能您正在为每个动态图像创建一个新的JFrameJava中的动画GIF图像有一个bug。与其他图像相比,内存没有增加
编辑
下面的示例运行时没有内存泄漏;但你需要从
import org.eclipse.swt.swt;
导入org.eclipse.swt.SWTException;
导入org.eclipse.swt.graphics.Color;
导入org.eclipse.swt.graphics.GC;
导入org.eclipse.swt.graphics.Image;
导入org.eclipse.swt.graphics.ImageData;
导入org.eclipse.swt.graphics.ImageLoader;
导入org.eclipse.swt.widgets.Display;
导入org.eclipse.swt.widgets.FileDialog;
导入org.eclipse.swt.widgets.Shell;
公共类礼物示例{
静态显示;
静态壳体;
静态气相色谱;
静态彩色背景;
静态图像加载器;
静态ImageData[]imageDataArray;
静态线程读取;
静态图像;
静态最终布尔值useGIFBackground=false;
公共静态void main(字符串[]args){
显示=新显示();
外壳=新外壳(显示);
外壳。设置尺寸(300300);
shell.open();
shellGC=新GC(外壳);
shellBackground=shell.getBackground();
FileDialog=新建FileDialog(shell);
setFilterExtensions(新字符串[]{“*.gif”});
字符串文件名=dialog.open();
如果(文件名!=null){
loader=新的ImageLoader();
试一试{
imageDataArray=loader.load(文件名);
如果(imageDataArray.length>1){
animateThread=新线程(“动画”){
@凌驾
公开募捐{
/*创建一个要绘制的屏幕外图像,并用shell背景填充它*/
图像偏移屏幕图像=新图像(显示,loader.logicalScreenWidth,loader.logicalScreenHeight);
GC offScreenImageGC=新GC(offScreenImage);
offScreenImageGC.后退背景(外壳背景);
offScreenImageGC.fillRectangle(0,0,loader.logicalScreenWidth,loader.logicalScreenHeight);
试一试{
/*创建第一个图像并在屏幕外图像上绘制*/
int imageDataIndex=0;
ImageData ImageData=imageDataArray[imageDataIndex];
如果(image!=null&&!image.isDisposed())image.dispose();
图像=新图像(显示,图像数据);
offScreenImageGC.drawImage(
形象,,
0,
0,
imageData.width,
imageData.height,
imageData.x,
imageData.y,
imageData.width,
图像数据(高度);
/*现在循环浏览图像,创建并绘制每个图像
*在外壳上绘制前,先在屏幕外图像上显示*/
int repeatCount=加载程序。repeatCount;
while(loader.repeatCount==0 | | repeatCount>0){
开关(imageData.disposalMethod){
案例SWT.DM_填充_背景:
/*在绘制之前填充背景色*/
颜色bgColor=null;
如果(useGIFBackground&&loader.backgroundPixel!=-1){
bgColor=新颜色(display,imageData.palete.getRGB(loader.backgroundPixel));
}
offScreenImageGC.setBackground(bgColor!=null?bgColor:shellBackground);
offScreenImageGC.fillRectangle(imageData.x,imageData.y,imageData.width,imageData.height);
如果(bgColor!=null)bgColor.dispose();
打破
案例SWT.DM_填充_之前:
/*在绘制之前恢复上一个图像*/
offScreenImageGC.drawImage(
形象,,
0,
0,
imageData.width,
imageData.height,
imageData.x,
imageData.y,
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);
}
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();
}
}