java graphics dispose_java – BufferedImage.getGraphics()导致内存泄漏,有没有修复?

我遇到一些框架API调用Buffered

Image.getGraphics()方法的问题,从而导致内存泄漏.这个方法的作用是它总是调用BufferedImage.createGraphics().在

Windows机器上,createGraphics()由Win32GraphicsEnvironment处理,它将侦听器列表保存在其字段displayChanger中.当我在BufferedImage someChart上调用getGraphics时,someChart的SurfaceManager(保留对someChart的引用)被添加到Win32GraphicsEnvironment中的侦听器映射中,从而防止someChart被垃圾收集.之后没有任何东西从侦听器地图中删除someChart的SurfaceManager.

通常,一旦调用getGraphics,阻止BufferedImage被垃圾收集的汇总路径如下:

GC Root – > localGraphicsEnvironment(Win32GraphicsEnvironment)

– > displayChanger(SunDisplayChanger) – >听众(地图) – > key(D3DChachingSurfaceManager) – > BIMG(BufferedImage的)

我本可以更改框架的代码,以便在每次调用BufferedImage.getGraphics()之后,我保留对BufferedImage的SurfaceManager的引用.然后,我获取localGraphicsEnvironment,将其强制转换为Win32GraphicsEnvironment,然后使用对BufferedImage的SurfaceManager的引用调用removeDisplayChangedListener().但我不认为这是解决问题的正确方法.

有人可以帮我解决这个问题吗?非常感谢!

更多细节和发现

我试图添加到我的UI的组件每次重新绘制时都会调用BufferedImage.getGraphics().因此,当组件重新绘制时,保留在displayChanger(在SunGraphicsEnvironment内部)的垃圾数量应该会增加.

然而,事情表现得非常奇怪:

当我在我的UI上计算我的操作肯定会触发重绘时,然后检查displayChanger中的垃圾监听器的数量与我的计数,它们不匹配. (例如,在点击之前有8位听众,我点击了60次.毕竟,只有18位听众.)

另一方面,如果我打开断点,并进入向displayListeners添加内容的过程,则每次单击都会在displayListeners中生成一个新条目.因此,displayListeners持有的每个BufferedImage都会变成垃圾.

我考虑过可以共享或重用SurfaceManager(可用作displayListeners的键)的可能性,但我的实验排除了这种可能性.我也考虑过缓存,我故意通过每次调用重绘独特的方式来防止缓存发生.不过,我不知道如何发生这种情况以及如何解决泄漏问题.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值