Garbage collection when using the Motoko Playground

Was just playing around with a Motoko playground example and before deploying it to the IC I received two options for the garbage collector (GC) strategy, copying or marking GC.

I’m assuming copy refers to the mark-copy GC and mark refers to the mark-sweep GC.

I don’t have much experience with garbage collection, so looked into a few resources that demonstrate these differences from a quick Google Search → they seem to favor the mark-copy algorithm, but also point a few less likely cases where mark-sweep outperforms.

A few questions on the the GC for Motoko, and some others which have been provoked by staring at this UI :slight_smile:

  1. How should Motoko developers think about garbage collection on the IC and how can we use it to our benefit in terms of message throughput performance, memory allocation, and cycle management with respect to storage costs?

  2. How does the Motoko playground force the canister that gets deployed to the IC to use garbage collection? How does “forcing” garbage collection affect the performance with respect to the metrics mentioned in question 1?

  3. On a separate note, what does the “Enable profiling” checkbox do?

@claudio @chenyan

  1. How should Motoko developers think about garbage collection on the IC and how can we use it to our benefit in terms of message throughput performance, memory allocation, and cycle management with respect to storage costs?

Roughly, the cost of copying GC depends on the size of the actively used memory, and the cost of marking GC depends on the size of the freed memory. So if the canister stores a lot of data, marking GC is preferred. Ideally, we should have a scheduler to decide which GC strategy to use based on the current memory usage, instead of fixing the strategy in the compile time.

  1. How does the Motoko playground force the canister that gets deployed to the IC to use garbage collection? How does “forcing” garbage collection affect the performance with respect to the metrics mentioned in question 1?

By default, the runtime won’t invoke the GC if the used memory is small. For most of the small changes, we won’t trigger the GC. “Forcing” garbage collection ensures we run GC for each message, so that we can measure the impact of the GC for small changes.

  1. On a separate note, what does the “Enable profiling” checkbox do?

Profiling instruments the canister code to produce a flamegraph for update methods. If you enable profiling, and call an update method in the Candid UI, you will see the flamegraph for this method. Before we have system level support, this only works with small cycle changes.

1 Like