Skip to content

Conversation

riccardobl
Copy link
Member

@riccardobl riccardobl commented Sep 1, 2025

The GLTF importer does a lot of memory copying of byte arrays in the heap, which makes it slow and often cause of OOMs on Android with big models, due to the limited heap space.

This PR switches to direct buffers to get around that limitation. It also uses buffer views where possible to slice and convert data instead of copying it around.

There is also some refactoring in the way streams are used, see comments for more details.

This is tested with the bistro scene used here: #2137

The loading time in my machine is:

  • Without this PR: 28228 ms
  • With this PR: 24503 ms

stream.read(bin);
data.add(bin);
ByteBuffer buff = BufferUtils.createByteBuffer(chunkLength);
GltfUtils.readToByteBuffer(stream, buff, chunkLength, -1);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes the way the stream is read, since stream.read, as it was used before, can return before the stream is read fully, if it hangs (eg. when loading from a slow disk or network)

animations = null;
skins = null;
cameras = null;
useNormalsFlag = false;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This stuff can be pretty huge on big scenes, so leaving it there is pretty bad for devices with limited memory

throw new IOException("Destination ByteBuffer too small: remaining=" + remaining + " < bytesToRead=" + bytesToRead);
}

ReadableByteChannel ch = Channels.newChannel(input);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In openjdk 21, the behavior for this is to transfer directly into the bytebuffer if the input is a FileInputStream, or, for generic streams, to fallback to use a small heap-located byte array with a maximum size of 8192 bytes.

Overall, I think using a larger chunk array could be beneficial, but I’ve decided this micro-optimization isn’t worth interfering with potential internal JVM optimizations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant