BufferedImage真的有人用么怎样防止内存溢出严重

时间:2008-06-04 20:24:22   来源:论坛整理  作者:  编辑:chinaitzhe
因为系统涉及到比较多的图形处理,而且重绘比较频繁,所以想在图形方面做些比较深入的工作。关于双

缓存,以前也早有听说,只是一直没怎么用,因为总听说JavaGui很多组建已经在内部实现了双缓存。当然GUi

内部是否实现了双缓冲,我没有仔细研究,只是我在自己的系统中绘图时发现,自己没实现双缓冲,画面并不

闪烁,只是稍微有点慢。基于这种原因,前几天我将所有图像采用了缓冲技术,绘制背景的具体代码如下:
Java code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/



BufferedImage offImg;

        if (offImg == null

            || offImg.getWidth() != d.width

            || offImg.getHeight() != d.height){

            offImg = null;

            offImg = new BufferedImage(

                d.width, d.height, BufferedImage.TYPE_INT_RGB);

            Graphics g2 = offImg.getGraphics();

            g2.setColor(bgColor);

            g2.fillRect(0,0,d.width,d.height);



            drawBack(g2);

            if (drawGrid)

                drawBackGrid(g2);

        }



    Graphics g = this.getGraphics();

        g.drawImage(offImg,0,0,d.width,d.height,null);




这样的话,每次图片重绘时,只是将BufferedImage复制到目标面板,经过测试,速度确实快了一点,但是

面板重绘一次至少要增加2M内容,刷新10多次,内存就溢出了。假如不用BufferedImage,而是直接在组件上绘

图,就没有内存溢出的问题,仔细查看程序,发现唯一可能浪费内存的地方只有图形复制方法g.drawImage

(offImg,0,0,d.width,d.height,null);
不知道大家有没有真的用过BufferedImage,假如用过是否也遇上了内存溢出的问题,应该如何解决呢?

网友回复:你用完了,dispose()销毁不就好了?
网友回复: if (offImg == null
¦ ¦ offImg.getWidth() != d.width
¦ ¦ offImg.getHeight() != d.height){
offImg = null;
offImg = new BufferedImage(
d.width, d.height, BufferedImage.TYPE_INT_RGB);
Graphics g2 = offImg.getGraphics();
g2.setColor(bgColor);
g2.fillRect(0,0,d.width,d.height);

drawBack(g2);
if (drawGrid)
drawBackGrid(g2);
g2.dispose(); // 加上这句.
}
上面的代码只有改变窗口的大小时, 才会创建新的BufferedImage, 刷新怎么会增加内存? 这点不明白.

Graphics g = this.getGraphics(); // 不知为什么要这样用, 而不是直接使用paint或者paintComponent提供的Graphics g.
g.drawImage(offImg,0,0,d.width,d.height,null);


网友回复:晕,这些代码只是简单的示意,
Graphics g = this.getGraphics();

paint(Graphics g);
有什么区别么?
网友回复:
引用 3 楼 shengli_liao 的回复:
晕,这些代码只是简单的示意,
Graphics g = this.getGraphics();

paint(Graphics g);
有什么区别么?


一个是直接获取当前控件所属Graphics对象
一个是重绘过程中调用的方法。。
难道有相同点嘛?

我能明白lz的意思,不过问题有点那个了- -
使用getGraphics(),在非重绘代码中进行描绘,你会面临一个很严重的问题:界面隐藏再显示后,你所描绘的内容会完全消失。
所以,慎用getGraphics()获取的对象进行描绘,你不知道什么时候你的操作就成了无用功。

paint(Graphics g)方法是重量控件的重绘过程中调用的方法。在此的代码每次重绘过程中都会被调用到。
对应的,轻量控件中有paintComponent方法。
网友回复:有没有真的在应用系统中大量使用过BufferedImage的人?
欢迎一起讨论,难道所谓的双缓存全都是骗人的?
网友回复:BufferedImage 没有问题,我们的图形界面一次翻页几十个BufferedImage一起更新

另外,双缓冲和内存溢出没有一点关系
网友回复:BufferedImage 没有问题,我们的图形界面一次翻页几十个BufferedImage一起更新

另外,双缓冲和内存溢出没有一点关系
网友回复:BufferedImage 没有问题,我们的图形界面一次翻页几十个BufferedImage一起更新,你更应该检查一下自己程序中是否存在内存问题而不是怀疑BufferedImage

另外,双缓冲和内存溢出没有一点关系
网友回复:dengdai...
网友回复:你理解的方向有问题
首先你现在面对的是内存问题,而不是双缓冲,双缓冲改善的不是内存,而是闪烁。请检查你的代码。
BufferedImage毫无问题,我们软件界面刷新一次需要更新几十个BufferedImage,也没出现所谓的内存溢出。
对于一个比较稳健的API,你所应该做的不是去怀疑,而是去尝试

网友回复:最后,你的几个方法理解上有问题。。。
至少g.drawImage不是用来复制图片的。。。。。
网友回复:假如g.drawImage不是复制图片,那Java只能被说成弱智。
事实上不用BufferedImage也没出现闪烁,
当然假如不用BufferedImage图形绘制稍微有点慢,
但是在操作过程中用户没有明显的感觉,因为只是10毫秒与100毫秒的差别。
假如你认为没有内存溢出,那只能说你没碰到这样的问题,
我一般在问问题前都先去网上查阅大量的资料,所以不用怀疑我在瞎问。
最后对于你的
=======================
对于一个比较稳健的API,你所应该做的不是去怀疑,而是去尝试
=======================
实在不敢苟同,对于天天客户要使用的实际应用系统,
假如开发商没有经过所有细节的严格测试,是极其不负责任的。
假如现在我将图形采用这类双缓冲,可能客户天天会找我的麻烦,
这就是我碰到的问题。
关键字:BufferedImage,有人,防止,内存,溢出,严重,

文章评论

共有 0 位网友发表了评论 此处只显示部分留言 点击查看完整评论页面