C++ Release API question

77 views
Skip to first unread message

marti...@gmail.com

unread,
Feb 28, 2018, 9:50:28 AM2/28/18
to FlatBuffers
For performance and memory efficiency purposes, my application requires to release the message buffer asynchronously. I would like to be able to call the Release API on FlatBufferBuilder and then call Clear or Reset on FlatBufferBuilder to create another message while the former buffer is processed (and eventually released independently by the application). However, looking at the code, it seems that the Release method does the same thing as the ReleaseBufferPointer method in the version of the code I have (1.8.0.4). In the documentation of ReleaseBufferPointer, there is a warning to the effect that a FlatBufferBuilder object should not be used after the ReleaseBufferPointer method is called. Is there a way I can reuse the FlatBufferBuilder after relinquishing ownership of the message buffer?

Martin

mikkelfj

unread,
Mar 1, 2018, 9:27:22 AM3/1/18
to FlatBuffers
Clearly this is for Wouter to reply regarding C++.

But if you use the FlatCC C api that is designed for detailed control over memory, the finalize call returns a copy of the buffer either to user allocated memory, or to a dynamically allocated buffer depending on the exact call. If dynamically allocated, the memory must be explicitly released with either free, or flatcc_builder_aligned_free, again depending on the exact call.

The internal memory used for buffer construction is a circular buffer of pages, and some small stacks. This memory will be reused after a release call. After release it is no longer possible to call finalize, but whatever you retrieved from an earlier buffer is now yours, and the internal memory can be reused immediately. The release call has a variant where you can decide if the internal memory should be reduced in size in case there were a large peak.

If more control is needed it is possible to customize the emitter to use a different structure than paged memory - it is like a write interface. Your application can consume those data directly as it is immitted (but the buffer will not be valid to read before it is all pieced together in linear memory). You can also customize the allocator used for the internal stacks by using a custom init call to the builder - this is also used with a customized emitter.

mikkelfj

unread,
Mar 1, 2018, 9:36:55 AM3/1/18
to FlatBuffers
I meant to say reset call, not release.

Wouter van Oortmerssen

unread,
Mar 2, 2018, 11:33:22 AM3/2/18
to mikkelfj, FlatBuffers
In terms of the C++ API, yes, either you own the buffer or FlatBufferBuilder does, not both. I suppose could add a function to recreate the buffer, but really, once you're done ReleaseBufferPointer the remaining FlatBufferBuilder is just an empty shell, and in terms of performance creating a new one is just as efficient.

--
You received this message because you are subscribed to the Google Groups "FlatBuffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to flatbuffers+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

marti...@gmail.com

unread,
Mar 5, 2018, 10:51:06 AM3/5/18
to FlatBuffers


 We will likely not be using FlatCC, but I'd like to understand how it manages memory as it seems to be more in line with what I'd expect the FlatBuffer library to do. There is a possibility we switch to FlatCC if it gives us better control over memory and there are memory issues running our application over time. My biggest worry is memory management when dealing with FlatBuffers. We will be creating a large number of FlatBuffer objects and I fear that if memory is dynamically allocated for each message, the heap space will get fragmented over time. From my understanding of your last message, FlatCC seems to already implement mechanisms that will prevent memory fragmentation and provides some APIs to customize this even further. My biggest wish would be that the FlatBuffers library uses some sort of memory pool for the objects it creates to avoid using the heap every time a FlatBuffer buffer is created. I'd also like to be able to tell the FlatBuffers library that some of the memory it used for a FlatBuffer buffer is currently held off in the application space for some time, but once the application is done using this memory, it can be returned to the memory pool and can eventually be reused for new FlatBuffer objects. From your initial response, it looks like FlatCC uses a memory pool of its own to allocate the buffers (using a circular buffer of pages). My issue with the C++ API is that to create a FlatBuffer object, I need a FlatBufferBuilder object and once I release the buffer that it uses, the FlatBufferBuilder object cannot be reused. I guess this is probably not an issue as much with FlatCC.

marti...@gmail.com

unread,
Mar 5, 2018, 11:00:19 AM3/5/18
to FlatBuffers
Wouter,

I read the initial response with regards to FlatCC, which seems to give some flexibility to the developer with regards to memory management. I am wondering if the C++ implementation offers something similar. How does the C++ implementation allocate memory when creating a FlatBuffers buffer. Where does the FlatBufferBuilder object gets its memory from when creating a buffer? Is it getting it from the heap? You mentioned that I may as well create a new FlatBufferBuilder for each FlatBuffer message that I create if I want to relinquish control of the buffer at any point in time, but I fear that this will create some issue with heap fragmentation. Can you comment on this?
To unsubscribe from this group and stop receiving emails from it, send an email to flatbuffers...@googlegroups.com.

Wouter van Oortmerssen

unread,
Mar 5, 2018, 11:52:47 AM3/5/18
to marti...@gmail.com, FlatBuffers
A FlatBufferBuilder contains a single dynamic memory allocation (which may be re-allocated if the initial size specified is too small).

It has an allocator interface that allows you to override this behavior, and force FlatBufferBuilder to create buffers wherever you want. This would allow you to get down to 0 allocations if you so desire.

I'm not sure what you mean by "message" and "object" in this case. Note that if you serialize multiple "objects" into a single FlatBufferBuilder, those all live in the same memory block, and no further allocation is performed.

To unsubscribe from this group and stop receiving emails from it, send an email to flatbuffers+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages