请教一下各位大侠这个错误怎么更好地处理错误名称:
       Exception in thread "Image Fetcher 3" java.lang.OutOfMemoryError: Java heap space 出错场景:
       我编写的是一个Swing程序,主界面有两个组建,左侧JList,显示某文件夹下的文件名,右侧JPanel,显示图像。当鼠标在在JList中移动到某一项的位置时,如果这个项对应的是个图像,就在右侧JPanel中显示这幅图像。这个JPanel并不是系统的JPanel,而是我自己写的继承JPanel的一个Panel类,其中重写了方法 protected void paintComponent(Graphics g),在其中调用 g.drawImage(image.getImage(), xs, ys, width, height, null)方法在Panel中话图。
       当图片较小时没有问题,当遇到大图片(2MB,3000×2000)时就会出现错误。从网上很多地方发现,只要是使用Image或ImageIcon处理较大文件时,就会不定期出现这个问题。从网上搜集的解决方法:
1. JVM默认最多只适用系统内存的1/64,修改这个值扩大内存可以解决问题(具体修改方法网上很多说明,所以这里不多说了)。
2.对于要显示在Panel上的图像,不将图像本身传给Panel显示,而是将其缩略图传过去显示,这样就节省了内存。我现在就是用这个方法。代码如下,其中的getScaledInstance方法就是按指定大小获取原始图像缩略图的方法。
    ImageIcon image = new ImageIcon(file.getAbsolutePath());
    //这里使用缩略图是为了防止JVM内存溢出
    if(image.getIconHeight() > 1000 || image.getIconWidth() > 1000){
            ImageIcon thumbImg = new ImageIcon(image.getImage().getScaledInstance(newWidth, new Height, ......));
    mf.getThumbnailPanel().setImage(thumbImg);//将缩略图送给Panel显示
    }else{
   mf.getThumbnailPanel().setImage(image);//将原始图送给Panel显示
    }
3. 在一个英文论坛上找到的,大概意思是说Image和ImageIcon这些类是一些包装地很高层的类,出现的问题我们无法跟踪,所以建议使用ImageIO等低级处理方式进行图片处理和显示。ImageIO我不是很清楚,但感觉他的大概意思是要用流的形式处理图像吧。我的疑问:
对于第一种方法,我认为不好,一个产品交给用户,我们不能要求用户去改JVM的参数吧,毕竟用户不是编程人员。
对于第二种方法,虽然暂时解决了问题,但对于一个有上万文件的文件夹,我没有测试过,所以不能保证不会再次产生问题。
对于第三种方法,我不是太了解底层的机制,所以不能说明。在这里,我想向各位高手请教一下,怎样才能更好地解决这个问题。谢谢

解决方案 »

  1.   

    你画图的时候,可以只画能显示出来的那部分。3000*3000的图片,你的panel显示不下吧,你可以只画panel能显示下的那部分,当拖动滚动条时进行重绘
      

  2.   

    1.jvm设置堆内存再大也没用,我是在JTextPane 做即时聊天应用,需要将图片,经常插入,我曾经把堆内存设置到1G,最后插了几百张图片还是内存泄露,如果是插几兆一张的图片,插入几张,就报错了。
    另外堆内存vm参数应该可以通过exe4j打包时设置,不需要用户设置。
    2.老是用缩略图显示 有时不符合实际要求啊,我做的应用必须直接显示大图,就算借鉴楼上的做法,只显示一小部分,滚动条拖动时重绘,但是最终显示出来之后,还是要显示那么大的图片
    3.我曾经见过一个人写的远程桌面程序,显示桌面那么大的图片,JPG格式 经常要绘图,没出问题,好像用的是sun 底层的API,但我没弄明白。
    4.这个问题困扰我一年了。
    5。如果哪个方法能够连续绘制一百张几兆的图片,就应该没有问题了