lwjgl 中的缓冲实用程序导致内存泄漏

Buffered utils in lwjgl causing memory leak

我正在创建一个 lwjgl OpenGL java 应用程序,这时我看到我的 ram 使用率越来越高而且没有停止。我逐行评论以查找泄漏,我发现了,内存泄漏发生在我将 matrix4f(在本例中为投影)上传到 GPU 供我的顶点着色器使用时。我使用 BufferUtils.createFloatBuffer(16); 并将其设置为一个变量以创建缓冲区以上传到 GPU 中的着色器,我使用的方法如下所示。

Code:

public void uploadMatrix4f(String variableName, Matrix4f matrix4f) {
        FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16); // Leak is occuring here.
        bind(); // This is just making sure that the shader that this is getting uploaded to is used.
        matrix4f.get(matrixBuffer);
        glUniformMatrix4fv(glGetUniformLocation(shaderProgramID, variableName),
                        false,
                        matrixBuffer
                        );
}

第一:那里没有内存泄漏。

BufferUtils.createFloatBuffer() 只是在幕后调用 ByteBuffer.allocateDirect() 来分配堆外内存(另外,它调用 asFloatBuffer() 来获取其上的 FloatBuffer 视图)。

一般来说,JVM 不会在对该内存的最后一次引用超出范围(即变得无法访问)后立即回收无法访问的内存。 JVM 的内存分配子系统(特别是垃圾收集器)针对吞吐量进行了调整,而不是针对最小内存占用。

并且为了实现高吞吐量,JVM 只会在需要时回收未引用的内存,也就是说,当系统内存(或者更确切地说是 JVM 本身允许的最大虚拟内存量)使用)达到耗尽状态。

因此,最终 JVM 回收该内存,而您将不会获得任何 OutOfMemoryError

此外,特别是对于堆外字节缓冲区,它们通常甚至需要两个完整的完整 GC 周期才能让垃圾收集器回收其本机内存。

你可以在 GC 启动之前限制 JVM 分配的内存量,设置允许分配的最大堆上内存量 -Xmx 和允许分配的最大内存量-XX:MaxDirectMemorySize.

的堆外内存

此外,LWJGL 3 提供了更多分配堆外内存的方法。为此阅读 https://blog.lwjgl.org/memory-management-in-lwjgl-3/