Stream: git-wasmtime

Topic: wasmtime / issue #9701 Wasm GC doesn't seem to collect ga...


view this post on Zulip Wasmtime GitHub notifications bot (Dec 02 2024 at 15:53):

epsylonix added the bug label to Issue #9701.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 02 2024 at 15:53):

epsylonix opened issue #9701:

Test Case

Running Kotlin-compiled Wasm guest requires Wasm GC proposal to be implemented by the runtime and Wasmtime now officially supports Wasm GC since version 27.0.0.

I'm embedding Wasmtime in Go (Wasmtime version in wasmtime-go updated to 27.0.0 locally) and running a benchmark that calls a simple guest function which makes small heap allocations. A minimal Kotlin guest function that reproduces the issue looks like this:

@OptIn(UnsafeWasmMemoryApi::class)
@WasmExport("test")
fun test() {
    withScopedMemoryAllocator { allocator ->
            val ptr = allocator.allocate(16)
            ptr.storeInt(1)
        }
}

Running a benchmark which calls this this function from the host repeatedly results in GC heap out of memory error almost instantaneously. According to the discussion at #wamtime this might be caused by an issue with Wasm GC implementation in Wasmtime.

Expected Results

Kotlin's withScopedMemoryAllocator is supposed to free all the memory allocated during the function call so this function shouldn't cause GC to run out of memory.

Actual Results

Wasm guest execution fails with a GC heap out of memory error after several calls to the function.

Versions and Environment

Wasmtime version or commit: 27.0.0

Operating system: macOS

Architecture: arm64

Extra Info

It would be great to have more details in the documentation on how Wasm GC works in Wasmtime. For example, Wasm GC uses it's own memory but I can't find any documentation on the default size of it or whether it can be configured.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 02 2024 at 15:54):

alexcrichton assigned fitzgen to issue #9701.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 03 2024 at 11:35):

epsylonix edited issue #9701:

Test Case

Running Kotlin-compiled Wasm guest requires Wasm GC proposal to be implemented by the runtime and Wasmtime now officially supports Wasm GC since version 27.0.0.

I'm embedding Wasmtime in Go (Wasmtime version in wasmtime-go updated to 27.0.0 locally) and running a benchmark that calls a simple guest function which makes small heap allocations. A minimal Kotlin guest function that reproduces the issue looks like this:

@OptIn(UnsafeWasmMemoryApi::class)
@WasmExport("test")
fun test() {
    withScopedMemoryAllocator { allocator ->
            val ptr = allocator.allocate(16)
            ptr.storeInt(1)
        }
}

Running a benchmark which calls this this function from the host repeatedly results in GC heap out of memory error almost instantaneously. According to the discussion at #wamtime this might be caused by an issue with Wasm GC implementation in Wasmtime.

Expected Results

Kotlin's withScopedMemoryAllocator is supposed to free all the memory allocated during the function call so this function shouldn't cause GC to run out of memory.

Actual Results

Wasm guest execution fails with a GC heap out of memory error after several calls to the function.

Versions and Environment

Wasmtime version or commit: 27.0.0

Operating system: macOS

Architecture: arm64

Extra Info

It would be great to have more details in the documentation on how Wasm GC works in Wasmtime. For example, Wasm GC uses it's own memory but I can't find any documentation on the default size of it or whether it can be configured.

Edit: actually, MemoryAllocator doesn't rely on Wasm GC and uses linear memory instead so I guess the GC heap out of memory memory is not caused by the memory allocated using allocator.allocate but probably it is by all the allocations Kotlin does automatically which do use Wasm GC heap.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 03 2024 at 11:36):

epsylonix edited issue #9701:

Test Case

Running Kotlin-compiled Wasm guest requires Wasm GC proposal to be implemented by the runtime and Wasmtime now officially supports Wasm GC since version 27.0.0.

I'm embedding Wasmtime in Go (Wasmtime version in wasmtime-go updated to 27.0.0 locally) and running a benchmark that calls a simple guest function which makes small heap allocations. A minimal Kotlin guest function that reproduces the issue looks like this:

@OptIn(UnsafeWasmMemoryApi::class)
@WasmExport("test")
fun test() {
    withScopedMemoryAllocator { allocator ->
            val ptr = allocator.allocate(16)
            ptr.storeInt(1)
        }
}

Running a benchmark which calls this this function from the host repeatedly results in GC heap out of memory error almost instantaneously. According to the discussion at #wamtime this might be caused by an issue with Wasm GC implementation in Wasmtime.

Expected Results

Kotlin's withScopedMemoryAllocator is supposed to free all the memory allocated during the function call so this function shouldn't cause GC to run out of memory.

Actual Results

Wasm guest execution fails with a GC heap out of memory error after several calls to the function.

Versions and Environment

Wasmtime version or commit: 27.0.0

Operating system: macOS

Architecture: arm64

Extra Info

It would be great to have more details in the documentation on how Wasm GC works in Wasmtime. For example, Wasm GC uses it's own memory but I can't find any documentation on the default size of it or whether it can be configured.

Edit: actually, MemoryAllocator doesn't rely on Wasm GC and uses linear memory instead so probably the GC heap out of memory error is not caused by allocator.allocate calls but by all the allocations Kotlin does automatically which do use Wasm GC heap.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 03 2024 at 15:36):

alexcrichton added the wasm-proposal:gc label to Issue #9701.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 04 2024 at 19:44):

fitzgen commented on issue #9701:

Thanks for filing an issue! I just got back from vacation and am in the process of catching up on things.

To confirm: you are using the default collector (DRC) not the null collector?

FWIW, it is expected that the null collector will not collect garbage and allocation will eventually exhaust the GC heap.

The DRC collector is a reference-counting collector and does not have a cycle collector, so it is also expected to leak GC objects if they are part of cycles. This is fundamental. Additionally, at this moment the DRC collector does not yet transitively decrement reference counts, so many acyclic garbage objects will be leaked as well (eg with a cons list, only the head would be collected and not anything in the list's tail). This latter bit of leakage is not fundamental nor intended long term, it just reflects that this is a young, WIP implementation.

Final note: can you attach the .wasm or .wat file as a test case? This makes it easier for Wasmtime maintainers to debug and diagnose issues, since it removes needing to set up and invoke/understand/debug the Kotlin toolchain.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 05 2024 at 09:36):

epsylonix commented on issue #9701:

Thank you! Yes, this was tested with the default DRC GC. Sure, will provide a .wasm file shortly.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 05 2024 at 10:15):

epsylonix commented on issue #9701:

Here is a .wasm file compiled using the code I've mentioned in the issue description. Calling the test function of the same module instance several times results in GC heap out of memory for me. withScopedMemoryAllocator makes allocations in linear memory so probably the issue can be reproduced without it.
gc_heap_out_of_mem.wasm.zip

Even if there is a memory leak, this code doesn't seem to produce a lot of garbage and it runs out of memory almost immediately. What is the size of the GC heap? Is it configurable?

view this post on Zulip Wasmtime GitHub notifications bot (Dec 05 2024 at 10:16):

epsylonix edited a comment on issue #9701:

Here is a .wasm file compiled using the code I've mentioned in the issue description. Calling the test function of the same module instance several times results in GC heap out of memory for me. withScopedMemoryAllocator makes allocations in linear memory so probably the issue can be reproduced without it.
gc_heap_out_of_mem.wasm.zip

Even if there is a memory leak, this code doesn't seem to produce a lot of garbage but it runs out of memory almost immediately. What is the size of the GC heap? Is it configurable?

view this post on Zulip Wasmtime GitHub notifications bot (Dec 05 2024 at 20:25):

fitzgen commented on issue #9701:

What is the size of the GC heap? Is it configurable?

At the moment it has a fixed, fairly small capacity of 512KiB. This is just intended as a default for running tests. The plan is to have all the same knobs that linear memories have, we just haven't gotten there yet.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 05 2024 at 20:25):

fitzgen commented on issue #9701:

And thanks for attaching the wasm files!


Last updated: Dec 23 2024 at 12:05 UTC