Eclipse下内存溢出错误(OutOfMemoryError)

写了一个图片缩放程序,当图片尺寸过大时会报错:

Exception in thread "Image Fetcher 0" java.lang.OutOfMemoryError: Java heap space

解决方法:

在Eclipse里选:Window->Preference->Installed JREs->Edit(选中jre),

在Default VM Arguments里输入-Xms256m -Xmx1024m,表示最小内存256M,最大1G,然后运行就可以了。

程序源码ImageBrowser.java :

import java.awt.Container;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;

public class ImageBrowser extends JFrame {
private static final long serialVersionUID = 1L;

JLabel lab = new JLabel();
JFileChooser chooser = new JFileChooser();
private String filePath;
private int height;
private int width;
private final double ratio = 0.2;
public ImageBrowser() {
   initial();
   setTitle("Image Browser --- No image");
   setSize(600, 400);
   setLocation(200, 150);
   setVisible(true);
   setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);  

}
public void initial() {
   // Create Menu
   JMenuBar menuBar = new JMenuBar();
   setJMenuBar(menuBar);

   JMenu menu1 = new JMenu("File");
   JMenu menu2 = new JMenu("Edit");
   menuBar.add(menu1);
   menuBar.add(menu2);
   JMenuItem openItem = new JMenuItem("Open");
   menu1.add(openItem);
   openItem.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
     chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        int r = chooser.showOpenDialog(null);
        if(r == JFileChooser.APPROVE_OPTION)
        {
         filePath = chooser.getSelectedFile().getPath();
         setTitle("Image Browser --- " + filePath);
         spread();
        }
    }
   });
   JMenuItem spreadItem = new JMenuItem("Spread");
   menu2.add(spreadItem);
   spreadItem.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
     spread();
    }
   });

   JMenuItem resumeItem = new JMenuItem("Resume");
   menu2.add(resumeItem);
   resumeItem.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
     resume();
    }
   });

   JMenuItem largeItem = new JMenuItem("Large");
   menu2.add(largeItem);
   largeItem.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
     height = (int)(height*(1+ratio));
     width = (int) (width*(1+ratio));
     lab.setIcon(getFixedBoundIcon());
    }
   });

   JMenuItem reduceItem = new JMenuItem("Reduce");
   menu2.add(reduceItem);
   reduceItem.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
     height = (int)(height*(1-ratio));
     width = (int) (width*(1-ratio));
     lab.setIcon(getFixedBoundIcon());
    }
   });

   JMenuItem exitItem = new JMenuItem("Exit");
   menu1.add(exitItem);
   exitItem.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
     System.exit(0);
    }
   });

   Container contentPane = getContentPane();
   JScrollPane sc = new JScrollPane(lab);
   contentPane.add(sc);
}
public void spread() {
   File file = new File(filePath);
   Icon ic = new ImageIcon(file.getAbsoluteFile().toString());
   int icHeight = ic.getIconHeight();
   int icWidth = ic.getIconWidth();
   Container contentPane = getContentPane();
   height = contentPane.getHeight();
   width = contentPane.getWidth();
   if((double)height/width>=(double)icHeight/icWidth)
    height = (int)(width*(double)icHeight/icWidth);
   else
    width = (int)(height*(double)icWidth/icHeight);
   lab.setIcon(getFixedBoundIcon());
}
public void resume() {
   try {
    Icon ic = new ImageIcon(filePath);
    height = ic.getIconHeight();
    width = ic.getIconWidth();
    lab.setIcon(ic);
   }
   catch(Exception e) {
    e.printStackTrace();
   }
}

public Icon getFixedBoundIcon(){
   double Ratio=0.0; //缩放比例
   try {
    File F = new File(filePath);
    Icon ret = new ImageIcon(filePath);
    BufferedImage Bi = ImageIO.read(F);
    if(1==1) { // ((Bi.getHeight()>height) || (Bi.getWidth()>width)) {
     if (Bi.getHeight()>Bi.getWidth()){
      Ratio = (new Integer(height)).doubleValue() /Bi.getHeight();
     } else {
      Ratio = (new Integer(width)).doubleValue()/Bi.getWidth();
     }
     File ThF = new File(filePath+"_"+height +"_"+width);
     Image Itemp = Bi.getScaledInstance (width,height,Image.SCALE_SMOOTH);
     AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(Ratio, Ratio), null);
     Itemp = op.filter(Bi, null);
     ImageIO.write((BufferedImage)Itemp, "jpg", ThF);
     ret = new ImageIcon(ThF.getPath());
    }
    return ret;
   }
   catch (Exception ex) {
    ex.printStackTrace();
   }
   return null;
}
public static void main(String[] args) {
   new ImageBrowser();
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java内存溢出可能有多种原因,其中一种可能是程序中的内存泄漏,另一种可能是程序中的无限循环。要排查内存溢出,可以使用内存分析工具来查找内存中的问题,也可以检查程序中是否有内存泄漏或无限循环,并采取相应措施来解决这些问题。 ### 回答2: Java内存溢出是指程序在运行过程中申请的内存超过了Java虚拟机所能提供的最大内存限制,导致程序异常终止或出现错误。为了排查Java内存溢出问题,可以采取以下几个步骤: 1. 检查错误信息:查看程序的错误日志或控制台输出,通常会提示内存溢出错误信息。错误信息可能包括“java.lang.OutOfMemoryError”等相关信息,能够帮助我们定位问题。 2. 分析堆栈信息:出现内存溢出时,通常会在堆栈信息中找到一些线索。查看堆栈信息,找出哪些方法或代码片段出现频繁调用,占用大量内存的可能性较大。 3. 使用工具分析内存:使用一些Java内存分析工具,如Eclipse Memory Analyzer(MAT)、VisualVM等,可以帮助我们定位问题。这些工具能够生成内存快照,并提供一个可视化界面来查看内存使用情况、对象引用关系等。通过分析内存快照,我们可以找到内存泄漏或过多使用内存的问题。 4. 代码审查:检查程序的代码,查看是否有明显的内存泄漏问题。例如未关闭数据库连接、未释放资源等。 5. 调整堆内存大小:可以通过增大Java虚拟机的堆内存限制来缓解内存溢出的问题。可以通过设置JVM选项-Xmx和-Xms来增大最大堆和初始堆的大小。 总之,Java内存溢出问题的排查需要结合错误信息、堆栈信息、内存分析工具等多种方法,并进行深入分析和定位。通过找出导致内存溢出的具体原因,以便采取相应的措施解决问题。 ### 回答3: Java内存溢出是指在程序运行过程中,因为申请的内存超过了JVM堆内存的限制,导致程序抛出OutOfMemoryError异常的情况。接下来我们将介绍一些排查内存溢出的常用方法。 第一步是分析错误日志。当程序抛出内存溢出异常时,JVM会生成错误日志文件,其中包含了异常的堆栈信息以及可能的原因。通过分析错误日志,我们可以初步了解是哪一部分代码导致了内存溢出。 第二步是使用内存分析工具。常用的内存分析工具有VisualVM、Eclipse Memory Analyzer等。这些工具可以帮助我们查看内存使用情况、对象的引用关系以及内存泄漏等信息。通过分析内存快照,我们可以找到内存溢出的具体原因。 第三步是检查代码中的资源泄漏问题。在Java程序中,未正确关闭的资源(如文件流、数据库连接等)会导致内存泄漏。因此,我们需要仔细检查代码,确保使用完资源后及时关闭。 第四步是调整JVM参数。通过调整JVM参数,可以增加JVM堆内存的大小或优化垃圾回收机制,以减少内存溢出的风险。常用的参数有-Xmx、-Xms和-XX:MaxPermSize等。 最后一步是代码优化。如果经过以上步骤仍然无法解决内存溢出问题,那么可能是代码设计存在问题。我们需要检查代码中是否有频繁创建大量对象的情况,是否有不必要的数据缓存等,以优化代码并降低内存消耗。 总之,解决Java内存溢出问题需要结合分析错误日志、使用内存分析工具、检查资源泄漏、调整JVM参数和代码优化等多个步骤,以找到并解决问题的根源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值