Java 浮动缓冲区占用越来越多的RAM
当我使用FloatBuffers时,它们会随着时间的推移占用越来越多的内存。我使用浮点缓冲区将转换矩阵放入其中,然后将其上载到着色器。所以我调用这个方法,它在每一帧创建浮点缓冲区Java 浮动缓冲区占用越来越多的RAM,java,opengl,lwjgl,Java,Opengl,Lwjgl,当我使用FloatBuffers时,它们会随着时间的推移占用越来越多的内存。我使用浮点缓冲区将转换矩阵放入其中,然后将其上载到着色器。所以我调用这个方法,它在每一帧创建浮点缓冲区 private static FloatBuffer matrixBuffer; public void uploadUniformMatrix4f(String name, Matrix4f matrix4f) { // Create a float buffer and put the matrix in
private static FloatBuffer matrixBuffer;
public void uploadUniformMatrix4f(String name, Matrix4f matrix4f)
{
// Create a float buffer and put the matrix in it
matrixBuffer = BufferUtils.createFloatBuffer(16);
matrix4f.get(matrixBuffer);
// Upload the float buffer as a matrix
GL20.glUniformMatrix4fv(getUniformLocation(name), false, matrixBuffer);
}
我已经尝试了memFree(matrixBuffer)代码>和matrixBuffer.clear()代码>但没有任何效果
每次调用时都在JVM堆之外创建新的缓冲区。也就是说,java垃圾收集器只引用ByteBuffer对象,而不引用它的数据,这与float[]data=new float[16]不同
因此GC将在需要清除JVM堆时清除本机内存
不推荐使用BufferUtils方法
LWJGL 3之前的版本完全依赖于allocateDirect(),通过
org.lwjgl.BufferUtils类。这门课在三年后仍然在那里
向后兼容,但不鼓励使用它。原因
很简单,allocateDirect()很可怕:
可以使用以下方法有效地传输OpenGL矩阵
import static org.lwjgl.opengl.GL20.glUniformMatrix4fv;
......
try (MemoryStack stack = MemoryStack.stackPush()) {
final FloatBuffer matrixBuffer = stack.mallocFloat(16);
// if you have more matrices like mvp, model, view, projection, normal
// you don't have to create new memory stack for them
// simply call stack.mallocFloat(16) as many times as you need
matrix4f.get(matrixBuffer);
glUniformMatrix4fv(getUniformLocation(name), false, matrixBuffer);
// call OpenGL shader program code here.
// When this try block ends - matrixBuffer native memory will be invalid. And OpenGL will crash when accessing the uniform memory already freed
}
创建浮动缓冲区,每一帧听起来都像是挂在内存上而不是释放它。在您的代码上运行探查器,以找出未释放此缓冲区的位置。@markspace我刚刚使用了JProfiler(实际上是第一次),并发现ByteBuffers和FloatBuffers正在占用越来越多的空间。此外,当注释掉着色器上载内容时,不会发生这种情况。您知道如何释放空间吗?内存最终会被释放,但直到JVM认为它应该释放内存,这可能是在根据您的物理内存大小分配了几十亿字节之后。您应该使用MemoryStack进行短期内存分配。请参阅:如果只初始化一次matrixBuffer
字段并重新使用缓冲区,也就足够了。@httpdigest谢谢!)现在,我立即使用BufferUtils创建缓冲区,而不是每次调用该方法。它工作得更好,但问题仍然没有解决