Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce memory allocations in Java #20243

Open
ibradwan opened this issue Feb 5, 2025 · 9 comments
Open

Reduce memory allocations in Java #20243

ibradwan opened this issue Feb 5, 2025 · 9 comments

Comments

@ibradwan
Copy link

ibradwan commented Feb 5, 2025

What language does this apply to?
Java

Describe the problem you are trying to solve.
Memory allocations could be optimized through using reusable objects. Right now, every message requires two objects, a builder and a message. Those objects aren't reusable, which makes it inefficient when serializing a lot of objects especially on limited-resources devices like low-end Android devices. Moreover, the excessive allocations of objects increase the garbage collection frequency which has its impact on the overall process perf.

Describe the solution you'd like
Two suggestions:

  1. Make the builder capable of emitting serialized byte array directly without the need to build another object that would hold the data.
  2. Make builders reusable through exposing a reset function.
@ibradwan ibradwan added the untriaged auto added to all issues by default when created. label Feb 5, 2025
@JasonLunn
Copy link
Contributor

Can you clarify - are you using Java or Java Lite on Android, @ibradwan ?

@ibradwan
Copy link
Author

ibradwan commented Feb 5, 2025

Java Lite.

@JasonLunn JasonLunn added java-lite and removed wait for user action untriaged auto added to all issues by default when created. labels Feb 5, 2025
@shaod2
Copy link
Member

shaod2 commented Feb 5, 2025

re: re-using builders

My take for this one is that even though it is supposed to be safe (build() and then clear() and then reuse builder) in simple cases (like..maybe in a for-loop?), it is not recommended as it basically reuses the same chunk of memory for different operations in the program, which might end up with same objects being used concurrently. Also, this might be even worse if the message is too complex or deeply nested.

One might consider doing this iff the performance is extremely critical.

@ibradwan
Copy link
Author

ibradwan commented Feb 5, 2025

Well the concurreny risk is there regardless, but I see your point that reusing the objects will inherently increase the chances of this happening. However, experienced developers working in low-end or high-scale enviroments would definitely perfer having the option to save up memory and GC time while knowing that they should implement the required measures to protect against concurrency issues (e.g., using builder pools per concurrent context/thread).

@shaod2
Copy link
Member

shaod2 commented Feb 5, 2025

Doesn't clear() meet your need here?

@ibradwan
Copy link
Author

ibradwan commented Feb 6, 2025

@shaod2 When I was looking into this, I found some very old posts mentioning that it's not safe to do so. I also didn't find any note indicating that this has changed since then. Anyway, if it's safe to do so, this would solve half of the problem, which is creating builders for every message.

Speaking of the other problem, is there a way to skip building the message object and directly emit the serialized byte array?

@ibradwan
Copy link
Author

@shaod2 Could you please confirm that reusing builders through the reset() function is safe?

@shaod2
Copy link
Member

shaod2 commented Feb 10, 2025

Currently I don't think there is way to get the serialized byte array from builder directly.. but it's an interesting idea to be evaluated. I've already put an agenda to talk about this internally.

Again, whether it's reset or clear, my view is that they should be safe under careful uses, as after build immutable copies are constructed, but they're in nature error-prone especially with more complex usages and message structures.

@ibradwan
Copy link
Author

Okay thanks for your reply. Will give it a shot and test it out and see how things go. Meanwhile, please keep us updated if there's anything new.

P.S. I was actually referring to 'clear()'.

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

No branches or pull requests

4 participants