Java3D离屏渲染内存泄漏

标签 java memory-leaks rendering java-3d off-screen

为了保存 3D Canvas 的快照,我通过以下方式扩展了 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() {}
}

我将其添加为宇宙 View 。主要策略如下:http://www.java2s.com/Code/Java/3D/PrintCanvas3D.htm

问题出在内存泄漏上。我的应用程序开始崩溃,当我尝试分析时,我发现 OffScreenCanvas3D 的实例占用了近 50MB,其中大部分来自两个 ArrayList。较小的一个包含 javax.media.j3d.RenderMolecule 的实例,较大的一个包含 Object 的实例,每个实例都包含 javax.media.j3d.RenderAtomListInfojavax.media .j3d.RenderMolecule.

有人可以建议我,我做错了什么吗?

更新

我想澄清的是,即使根本没有调用doRender(例如,启动应用程序并且没有采取更多操作),内存仍在累积。下面我将添加图像以更好地显示情况。

第一个是空闲运行应用程序的内存图。 memory grap

第二个是对象占用内存的饼图。这里(a)是为OffScreenCanvas3D实例分配的内存,(b)是所有其他对象占用的内存。 memory pie chart

在下面您还可以看到 dirtyDlistPerRinfoListdirtyRenderMoleculeList 占据了大部分空间。任何带有前缀 dirty 的东西都会给我一种糟糕的代码的感觉,我不知道为什么 enter image description here

更新2

问题似乎出在接下来的部分:

  1. dirtyDlistPerRinfoList 对象添加到 RenderBin 类的 updateCanvasResource 方法中。所有 Canvas 都会发生这种情况。
  2. dirtyDlistPerRinfoListRenderBin 类的 updateDirtyDisplayLists 方法中清除。
  3. updateDirtyDisplayLists 是从 Renderer 类中的 doWork(一个可怕的 1300 行方法)为每个正在渲染的 Canvas3D 调用的。

有一件事是,离屏 Canvas 不会一直渲染,而是仅在要保存图像的那一刻渲染。是的,保存图像后,dirtyDlistPerRinfoList 中积累的所有内存都被释放。

所以主要问题是:

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?

最佳答案

什么都没有。 Java 3D 应用程序至少需要 25+ MB 内存加上在 RenderMolecule 和 RenderAtomListInfo 类中存储模型所需的内存。请注意,BufferedImage 也会消耗大量内存,具体取决于其大小。不时调用 System.gc() 可能会有所帮助。 BufferedImages 并不那么容易删除。

关于Java3D离屏渲染内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13680558/

相关文章:

java - 为什么java Native Memory Tracking中的内部内存在增加

java - OpenGL + LWJGL - glColor4d() 没有正确着色形状

c# - 为什么 ListView 对某些字符的渲染速度如此之慢?

java - 如何使用 PEM 格式的 RSA 公钥解码 JWT token ?

java - LibGdx android 访问 .txt 文件并将其转换为字符串

ios - 内存泄漏声明常量

c++ - 是否可以设置全局 QPainter 默认渲染提示?

java - Hadoop MapReduce作业启动但找不到Map类?

java - 如何在非 TabActivity 的 Activity 中创建 tabHost

node.js - 哪些诊断工具可用于Node.js应用程序?