Definitely you are right, it makes the code a bit more complicated/error prone.
What I have in mind, is that we use the a default implementation of the interface I mentioned, that just delegates to the java memory manager, so the free call would do nothing and the object will be freed by the GC.
Users of roaring, can do object pooling, etc. to reduce the temporary memory created by roaring (switching between containers, etc.).
So from a benefit point of view, it depends on the user's implementation, we just give the ability and make sure to free resources when possible.
I have the change in a forked repo and with the right object pooling, I got up to 60% reduction in char[] and long[] in my application
Ill do the change, and we can discuss on the PR.