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

Officializing the Incremental GC #4340

Merged
merged 2 commits into from Jan 5, 2024
Merged

Conversation

luc-blaeser
Copy link
Contributor

Officializing the Incremental GC

After a longer beta testing phase and some fine-tuning, we could officilalize the incremental garbage collector.
This would be next intermediate step before making the incremental GC the default GC in Motoko.

Some advice may be helpful to be given to developers, ideally also in a forum post, once we have declared the GC production ready.

Note

The incremental GC is enabled by the moc flag --incremental-gc (#3837) and is designed to scale for large program heap sizes.

While resolving scalability issues with regard to the instruction limit of the GC work, it is now possible to hit other scalability limits:

  • Out of memory: A program can run out of memory if it fills the entire memory space with live objects.
  • Upgrade limits: When using stable variables, the current mechanism of serialization and deserialization to and from stable memory can exceed the instruction limit or run out of memory.

Recommendations

  • Test the upgrade: Thoroughly test the upgrade mechanism for different data volumes and heap sizes and conservatively determine the amount of stable data that is supported when upgrading the program.
  • Monitor the heap size: Monitor the memory and heap size (Prim.rts_memory_size() and Prim.rts_heap_size()) of the application in production.
  • Limit the heap size: Implement a custom limit in the application to keep the heap size and data volume below the scalability limit that has been determined during testing, in particular for the upgrade mechanism.
  • Avoid large allocations per message: Avoid large allocations of 100 MB or more per message, but rather distribute larger allocations across multiple messages. Large allocations per message extend the duration of the GC increment. Moreover, memory pressure may occur because the GC has a higher reclamation latency than a classical stop-the-world collector.
  • Consider a backup query function: Depending on the application case, it can be beneficial to offer an privileged query function to extract the critical canister state in several chunks. The runtime system maintains an extra memory reserve for query functions. Of course, such a function has to be implemented with a check that restricts it to authorized callers only. It is also important to test this function well.
  • Last resort if memory would be full: Assuming the memory is full with objects that have shortly become garbage before the memory space has been exhausted, the canister owner or controllers can call the system-level function __motoko_gc_trigger() multiple times to run extra GC increments and complete a GC run, for collecting the latest garbage in a full heap. Up to 100 calls of this function may be needed to complete a GC run in a 4GB memory space. The GC keeps an specific memory reserve to be able to perform its work even if the application has exhausted the memory. Usually, this functionality is not needed in practice but is only useful in such exceptional cases.

@luc-blaeser luc-blaeser self-assigned this Dec 21, 2023
@luc-blaeser luc-blaeser marked this pull request as ready for review December 21, 2023 09:33
@luc-blaeser luc-blaeser added the automerge-squash When ready, merge (using squash) label Dec 21, 2023
@luc-blaeser luc-blaeser removed the automerge-squash When ready, merge (using squash) label Dec 21, 2023
Copy link

github-actions bot commented Dec 21, 2023

Comparing from 4271e7c to 57ff4db:
The produced WebAssembly code seems to be completely unchanged.

@crusso
Copy link
Contributor

crusso commented Jan 2, 2024

I wonder when we should make it the default?

@luc-blaeser
Copy link
Contributor Author

I wonder when we should make it the default?

I thought that we could maybe wait for one more month to see if there is user feedback after this "blessing" and then make it the default.

@luc-blaeser luc-blaeser added the automerge-squash When ready, merge (using squash) label Jan 5, 2024
@mergify mergify bot merged commit b412a4b into master Jan 5, 2024
10 checks passed
@mergify mergify bot deleted the luc/officialize-incremental-gc branch January 5, 2024 09:09
@mergify mergify bot removed the automerge-squash When ready, merge (using squash) label Jan 5, 2024
@ggreif
Copy link
Contributor

ggreif commented Jan 5, 2024

Maybe we should add a (GH) wiki page with the decision procedure for when not to use incremental GC, as well as a pros/cons table about each GC choice.

@rossberg
Copy link
Contributor

rossberg commented Jan 5, 2024

Did the forum announcement just officially recommend the direct use of Prim functions? That seems like a very bad precedent. ;)

@luc-blaeser
Copy link
Contributor Author

Did the forum announcement just officially recommend the direct use of Prim functions? That seems like a very bad precedent. ;)

Thanks for noticing. I agree. We should better offer some metrics in the base library. I will prepare such change and then update the post.

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.

None yet

4 participants