为了能够保存我的 3d 画布的快照,我Canvas3D
以以下方式进行了扩展:
class OffScreenCanvas3D extends Canvas3D {
OffScreenCanvas3D(GraphicsConfiguration graphicsConfiguration, boolean offScreen) {
super(graphicsConfiguration, offScreen);
}
public BufferedImage doRender(int width, int height) {
BufferedImage bImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
ImageComponent2D buffer = new ImageComponent2D(ImageComponent.FORMAT_RGBA, bImage);
setOffScreenBuffer(buffer);
renderOffScreenBuffer();
waitForOffScreenRendering();
bImage = getOffScreenBuffer().getImage();
setOffScreenBuffer(null);
return bImage;
}
public void postSwap() {}
}
我将它添加为宇宙的视图。这里描述了一个主要策略:http ://www.java2s.com/Code/Java/3D/PrintCanvas3D.htm
问题在于内存泄漏。我的应用程序开始崩溃,当我尝试分析时,我发现一个实例OffScreenCanvas3D
占用了将近50MB,其中大部分来自两个ArrayList
s。较小的包含 的实例,javax.media.j3d.RenderMolecule
较大的包含 Object 的实例,每个实例都包含javax.media.j3d.RenderAtomListInfo
和javax.media.j3d.RenderMolecule
。
任何人都可以建议我,我做错了什么?
更新
我想澄清的是,即使doRender
根本没有调用(例如,应用程序已启动并且没有采取更多操作),内存仍在累积。下面我将添加可以更好地显示情况的图像。
第一个是空闲运行应用程序的内存图。
第二个是对象占用内存的饼图。这(a)
是为 的实例分配的内存OffScreenCanvas3D
,(b)
是所有其他对象占用的内存。
同样在下面,您可以看到dirtyDlistPerRinfoList
并dirtyRenderMoleculeList
占用大部分空间。任何带有dirty前缀的东西都给我一种代码不好的感觉,我不知道为什么
更新2
看来问题出在接下来的部分:
- 的对象
dirtyDlistPerRinfoList
被添加到类的updateCanvasResource
方法中RenderBin
。这发生在所有画布上。 dirtyDlistPerRinfoList
updateDirtyDisplayLists
在类的方法中被清除RenderBin
。updateDirtyDisplayLists
对于每个正在渲染的 Canvas3D,在类中从doWork
(可怕的 1300 行方法)调用。Renderer
事情是offScreen画布不是一直在渲染,而是在图像将要保存的那一刻。是的,保存图像后,所有累积的内存dirtyDlistPerRinfoList
都会被释放。
所以接下来的主要问题是:
的数据
dirtyDlistPerRinfoList
不断添加到未渲染的画布中,因此不会删除内存。这是我的Java3D错误的错吗?