To enable saving of a snapshot of my 3d canvas, I've extended Canvas3D
in the next way:
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() {}
}
And I add it as a view to the universe. And a main strategy is described here: http://www.java2s.com/Code/Java/3D/PrintCanvas3D.htm
The problem is in memory leak. My app started to crash and when I tried to profile, I've found out that an instance of OffScreenCanvas3D
occupies almost 50MB and the most part of it comes from two ArrayList
s. Smaller one contains instances of javax.media.j3d.RenderMolecule
and a larger one contains instances of Object each containing javax.media.j3d.RenderAtomListInfo
and javax.media.j3d.RenderMolecule
.
Can anybody suggest me, what I'm doing wrong?
UPDATE
I want to clarify that even when doRender
is not called at all (eg. applications is launched and no more actions are taken) the memory is still accumulating. Below I'll add images that will show the situation better.
First one is a memory graph of an idle running application.
The second one is a pie chart of memory taken by objects. Here (a)
is the memory allocated for an instance of OffScreenCanvas3D
, (b)
is the memory ocupied by all the other objects.
Also below you can see that dirtyDlistPerRinfoList
and dirtyRenderMoleculeList
take most of the space. Anything with prefix dirty gives me a feeling of a bad code, I don't know why
UPDATE2
It seems that the problem is in the next parts:
- Objects of
dirtyDlistPerRinfoList
are added in theupdateCanvasResource
method of theRenderBin
class. This happens with all the canvas. dirtyDlistPerRinfoList
is cleared inupdateDirtyDisplayLists
method of theRenderBin
class.updateDirtyDisplayLists
is called fromdoWork
(a horrible 1300 lines method) in classRenderer
for every Canvas3D that's being rendered.
A thing is that offScreen canvas is not being rendered all the time, but just in the moment when the image is going to be saved. And yes, after saving the image, all the memory accumulated in dirtyDlistPerRinfoList
is freed.
So the main question is next:
Data of
dirtyDlistPerRinfoList
is continuously added to canvas that's not being rendered and so the memory won't be deleted. Is this my fault of Java3D bug?