-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Consider splitting up System.Text.Json
tests to allow running them completely with wasm/AOT
#87078
Comments
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsRunning
We run into limits while trying to run this test suite, and try to work around that in different ways. It would be extremely useful to possibly run the tests in parts. But I'm not sure how we could split this up. We could either split this into multiple projects if there is a good logical boundary for that. Or we could pick handful of big classes, and explicitly run them in a separate helix job. cc @kg @pavelsavara for more details on the issues we are running into.
|
S.T.J is also very close to the limit in the wasm interpreter configuration. If you raise the Jiterpreter limit by a few more megabytes the test suite will also hit V8's heap size limit and crash. So I think we've been just barely staying below this 2GB threshold for a while. |
In order to understand the problem correctly, is this an issue of assembly size, number of tests, or specific tests having a very deep stack? |
@eiriktsarpalis this is also a problem for Native AOT. The Json tests have been failing in the runtime-extra-platforms runs ever since they got enabled:
It's an OOM. The test does compile for me locally but takes forever, consumes gigabytes of memory, and compiles into a 150 MB executable with a 1.5 GB PDB. That's rather large. There are three issues:
Getting rid of the generic recursion would be probably the best first step. If we can turn some of the structs in the test into classes, that would help too. The generic virtual method is a huge problem because of the recursion but it will probably scale pretty poorly for large JSON models in general. I have reasons to believe the recursion is still around handling of
|
If you want to see the extent of it, System.Text.Json.SourceGeneration.Roslyn4.4.Tests.zip You'll see something like this: |
AFAIK stack depth is not the problem here, for the wasm interp scenario the native heap as a whole is growing until it hits a limit. If I had to guess it's probably a mix of type info, generated interpreter code, jitted wasm code (for the interp+jiterp scenario), etc. I don't know offhand how to get measurements out of the mono runtime on this stuff but if you need measurements I can probably figure it out. In the V8 console scenario, the native heap has to approach 2GB of allocated space before this happens. I'm not sure why the wasm AOT version is running out of memory, to be honest - I would expect it to use less memory, but it's possible that loaded AOT binaries count against V8's heap size limit. |
We're getting OOM-killed in the CI. See dotnet#87078. I'm also changing how we do warning suppressions. We still need to suppress most of AOT warnings because xUnit/tests are not warning clean, but the warning about generic recursion is critical for the product and should fail the build.
We're getting OOM-killed in the CI. See #87078. I'm also changing how we do warning suppressions. We still need to suppress most of AOT warnings because xUnit/tests are not warning clean, but the warning about generic recursion is critical for the product and should fail the build.
I think that's unavoidable given the nature of testing serializers, effectively we tend to define one new type per test and many of these tests need to include coverage for structs (to make sure that each facet of the serializer correctly accounts for struct semantics). I think we could try cutting a few struct definitions here and there when not strictly necessary from a test coverage perspective but I wouldn't expect huge gains from that exercise.
I recently merged #80755 that made changes to |
@MichalStrehovsky new sizes after #87211 got merged. |
With #87276 it looks like the total size has dropped to 60 MB. Should we try re-enabling the tests once merged? |
PR is merged, feel free to rebase your PR branch. |
It still fails:
|
Adding pre-test yield to few test classes will allow JS engine to run timer loops. It may give our GC chance to run. xunit syntax is
But v8 timer loop is strange, still worth trying, I think. |
Did some experiments:
So it looks like the linear memory usage is somewhere between 512mb and 1gb. Not sure what causes v8 to consume 2gb of memory. |
I can reproduce this when running with |
@pavelsavara @kg are there js objects we could be leaking/retaining? |
Could this be heap growth? i.e. growing from 512mb to 1gb requires being able to allocate contiguously 512mb + 1gb in the v8 perm gen, and it's not big enough |
That unit test doesn't do any JS interop. The only one is that we hold Task/Promise pair for the main method. I'm thinking about emscripten's posix emulation leaking. And I guess I should better understand how we allocate/free memory. I don't know what runtime/src/mono/mono/sgen/sgen-marksweep.c Lines 2129 to 2138 in b9c9964
|
A major GC block has 16kb and when we allocate blocks we allocate them in chunks (of 32 blocks at a time). Each block will be in a free list and will be used by the GC when needed. After a collection, in |
To do more testing see #88825 (comment) |
It's unlikely we'll be able to address this in .NET 8, moving to future. |
From #88825 (comment)
|
closing as resolved but the large trim unfriendly test assemblies are still very much a thing |
Running
System.Text.Json.Tests
with wasm/AOT crashes V8, and chrome. Issue: #86164We run into limits while trying to run this test suite, and try to work around that in different ways. It would be extremely useful to possibly run the tests in parts. But I'm not sure how we could split this up. We could either split this into multiple projects if there is a good logical boundary for that. Or we could pick handful of big classes, and explicitly run them in a separate helix job.
cc @kg @pavelsavara for more details on the issues we are running into.
cc @eiriktsarpalis
The text was updated successfully, but these errors were encountered: