BIG VBOs Memory Consumption

Started by Jakes, March 24, 2021, 10:50:56

Previous topic - Next topic

Jakes

I was trying to understand why my program was consuming so much memory after creating a big VBO (2.884.802 triangles), and after removing and disposing every object and structure from my program the memory was still high, meaning that the mesh data is somehow stored in RAM memory as well as VRAM memory.

is this true?

PS: I did another test, and using the same process to build a mesh with less poly count (200.000 triangles) the memory consumption was way lower. So I'm only guessing that there is some sort of data or buffer stored in RAM memory.

KaiHH

You likely created the memory as a NIO Buffer in system ram in the first place, and then uploaded that NIO Buffer to the OpenGL buffer object in GPU memory and the JVM did not (yet) free the system-memory-allocated NIO Buffer because it did not need to.
What you can do to decrease the apparent allocated system memory of your process is to first allocate the OpenGL buffer object with the appropriate size using the sized glBufferData overload (without supplying it a NIO Buffer), then glMapBuffer() the buffer and use the returned NIO Buffer to fill the host-visible, mapped memory region and afterwards, glUnmapBuffer() the memory again.
At least on Windows, memory-mapped, host-visible GPU memory does not count towards the "system memory" metrics of the process.

Jakes

thanks,

so I tried changing the process to have those steps:

glBindBuffer(GL_ARRAY_BUFFER, vertexVBO);
		glBufferData(GL_ARRAY_BUFFER, verticesBuffer.length, GL_STATIC_DRAW);
		ByteBuffer b = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
		b.put(verticesBuffer);
		glUnmapBuffer(GL_ARRAY_BUFFER);


But to no avail. So the mem consumption seems to be the same as when using glBufferData with the buffer in it.


KaiHH

You probably didn't understand what I was trying to say in my first answer.
You obviously still have a NIO Buffer allocated in system memory that you then just copy into the mapped opengl buffer object memory.
What is the variable 'verticesBuffer''. That surely is either an array or a NIO Buffer that you allocated before in system memory and that is what shows in your system memory consumption metric.... not the OpenGL buffer object...
So, as I was saying, if you want to avoid that you must put the vertices into the mapped buffer without allocating another NIO Buffer or array and simply copying that into.

Jakes

Hmm, I understood that the issue was the Buffer data structure, and not using an array in and of itself, but yes, it is an array.

So in the same line of thinking, as for me to remove the array altogether was a super change in my mesh building process, instead, assuming it was a java issue, I proceed to call System.gc(), just to test it was unused memory wainting to be cleaned, and it turned out it was.
But again, thanks for the tips and help improve the loading process without consuming much memory in one step, and on how to use the glMapBuffer.

Regards,


KaiHH

Quote from: Jakes on March 25, 2021, 10:54:43
Hmm, I understood that the issue was the Buffer data structure, and not using an array in and of itself, but yes, it is an array.
No. The issue simply was that you allocated that memory in JVM/system memory... be it a NIO Buffer or a Java array, it doesn't matter.
And yes, the JVM would eventually have reclaimed that memory when it needed to. The JVM can and will first allocate as much memory as it can before it starts to garbage-collect.
You can also control how much heap memory the JVM will use with the `-Xmx` JVM argument.