因项目需要,自己用java swing写了个图片浏览程序,在不停地浏览或缩放时,内存只会上升而不会下降,直到最后抛出OutOfMemoryError。不知这里有没有人碰到过类似的问题,怎么在程序中释放内存?XP中的image & fax viewer,每次浏览只会增加图片大小的内存,显示完毕后就马上将那点内存释放掉。java中有类似的方法吗?解决立马给分!

解决方案 »

  1.   

    我是用JLabel显示图片的,可结果是每次放大图片时内存消耗特别大,比如,显示一个2M的图片,javaw.exe就占用近40M的内存,放大1.25*1.25倍后,就80多M了,再下去就报OutOfMemoryError
      

  2.   

    用JLABEL显示图片,它会把图片都转换为最占体积的BMP处理. BMP的弱智是向来有名的.
    所以最好找针对JPG的图形显示控件,就是说那种不会自动转换成BMP的.
      

  3.   

    调高虚拟机参数是不是办法的办法...起码不会报错,但还是吃内存
    我现在采取的方法是全部放大的,就是先得到原图的ImageIcon对象、高度和宽度,再按照适当的比例进行放大。我找过sourceforge上一个开源的JImageView,这个项目也有和我遇到的一样的毛病,很容易产生OutOfMemoryError。
    我也认为在JLabel中显示图片是把各种类型的图片按像素读然后再绘出来的,虽然我是直接用setIcon()这个方法,但我看过swing底层代码,也是通过java2D绘出来的,这个应该很耗内存。
    专门找JPG显示控件不现实,这样还需要gif、ico、png、bmp...各种控件。
      

  4.   

    用ClassLoader,用完了就及时释放
      

  5.   

    一般java使用Reference对象就可以释放内存,如SoftReference或WeakRefernce等,具体看javadoc,但这并不像C那样可以随意释放,最终还是得看jvm处理。
    如果这个处理不好,只有调高jvm内存参数了...
    高手呢?给点正解吧...
      

  6.   

    我在处理图片问题上也会经常出现异常,好像JAVA对图片的处理就是显示心有余而力不足了些
    能不能用别的方法来做图片处理呢,比如JAI
      

  7.   

    sourceforge上的jimageview就是用jai的,我使用了一下,也不行
      

  8.   

    我认为lz的方法不对,我的实现是根据当前的缩放比例,计算出原图在画布上显示的区域,然后只绘制显示的区域。画布可以是一个JPanel,要注意的是无论缩放比例是多大,画布的尺寸都是不变的,你需要做的是计算出当前的缩放比例和固定的画布尺寸下,原图显示的区域,然后只绘制这部分区域。进行缩放操作时也不是真的缩放原图,而是在绘制时缩放那块显示区域,这样可以提高速度又不会有内存的问题了。
      

  9.   

    其实我觉得 JAVA 2D 还是很好用的,还是看你怎么用了。方法不对,换一个开发平台还是会有类似的问题。
      

  10.   

    缩放是没问题的,也是次要的,现在主要关心的是图片导入的瞬间以及导入后内存的变化。比方说,一个2M左右的jpg图片(一般数码相机拍出来的都这般大了),用new Image(图片)时,执行到这一步内存就彪升,起码要大30M左右,相反,看看Windows Image&Fax Viewer或者Acdsee,导入2M的jpg图片时内存变化也就升2M左右,而且一旦导入完毕,内存就会释放掉。我想知道的是,java也能不能实现类似的效果?
      

  11.   

    JAVA为什么会升这么多的内存,我也深有体会
    我导入大的图片时,JAVA的内存会多很多,像我把几十张图片一起导入,这些图片加起来只有2M左右,但是在JAVA里,却要用掉120M的内存,挺奇怪的,不知道JAVA的图片管理是怎么实现的.
    怎么会这么耗内存呢?
      

  12.   

    哪应该与new Image的实现有关了
      

  13.   

    肯定是和new Image()有关了,但怎么样才能消除这影响呢?
      

  14.   

    经过实践,发现先把图片全部以二进制流的方式读入内存,这个时候是不占什么内存的,也就是它图片多大,就占多少内存,然后当你想用Image对象的时候,你就用二进制流对象来构造一个对象,要用就构造,不用就释放,这样对内存会好一些
    不过,这样做也有一个不好的地方,那就是,很占CPU的资源
      

  15.   

    问题是怎样来释放,java不像c,很难控制的。
    我同事也用二进制流方式处理,但是效果依然不大...
    lbfhappy(千里冰封)有没有实际的例子,拿出来讨论一下?
      

  16.   

    释放确实是一件很麻烦的事,我是这样做的
    构造好了一张以后,把上张图片的引用设为null,然后显示的调用System.gc(),这样一般是可以收集垃圾的,但是还是不能确定,我就试过我同样的程序,在有些电脑上要吃60M内存
    在有些电脑上却要吃掉90多M
      

  17.   

    是啊,System.gc()不是强制性的。用了mantaihu说的Reference,也没看出什么大的变化,你也可以试试