-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
dart2js uses too much memory #27883
Comments
We are doing some long term changes that can help with this, but you wont see the benefits for a while. Is observatory built using
transformers:
...
- $dart2js:
$include: []
The reason I suggest this is that we have noticed on some customer apps that pub-build increased the overall memory pressure by a lot (sometimes 50% more on some large complex apps). This was more so on apps that had lots of transformers though, so YMMV. |
Observatory is built directly with I think there were also changes that improved memory usage in Is this still a problem? Can you give that flag a try? It was also recommended here: #32503 (comment) |
I see the dart2js invocation has a peak RSS of 900MB. (We can also no longer build on ARM/ARM64 hosts because of build tool issues that probably won't addressed until Fuchsia starts self-hosting.) |
I do not expect the various optimization flags to make much difference to the memory requirements of dart2js. |
CC @vsmenon |
We're continuing to have increased build memory issues. For a couple of our applications we're in the neighborhood of 25G: At this point we have pretty limited recourse:
I'd love to hear any advice you've gleaned from other LARGE Dart apps. |
@todbachman-wf @trentgrover-wf - thanks for following up and sharing your details. I have a few questions for you:
We have recently added a mode in dart2js to split the build in 3 steps: front-end, global-analysis, and backend, but I'm not sure how much it will help. The steps run serially and do the same amount of work, the only difference is that data is not kept in memory, it is dumped and re-read from disk. Technically we save all the data we use and we would have GC'd everything else, but if we were leaking anything, this split could potentially get rid of that. The backend step can be sharded into many subprocesses, these shards are then merged by a single step that may again use as much memory as before. The flags for splitting the build are not well documented because they are mostly used behind the scenes in build systems like bazel. Unfortunately they are not used in webdev at this time, so there is not an easy way to enable them without some work on our side. If you believe this could help on your end, we can try to figure out how to get it out to you. @jakemac53 - what are your thoughts on how hard it would be to integrate the split dart2js steps in webdev? |
For an idea of scale: Roughly 4 million lines of Dart code, about 240 packages. |
It should be feasible to do the split steps for dart2js in webdev (build_web_compilers really), but I don't know that it really buys anything externally? Probably not more than two days of work. I think the main reasoning for that feature though is dealing with our timeout restrictions internally which don't really apply externally? We also won't get the parallelism benefits that we get with bazel, so it seems like it would not help much.
Actually, this could easily be part of the problem. By default we use this formula to determine the parallelism: This is overridable using the |
Great to know - we have some internal apps of ~5 million LOC and we build them under 12Gb of RAM. I'm more and more thinking that parallel builds might be what's causing the biggest issue here. Let us know if it helps limiting the number of workers as Jake suggested! |
@sigmundch Below you'll find the compilation log for our main application.
The following charts are for this actual compilation in CI. I modified the CI run so that all it does is a pub get followed by The only dart2js flags we've been using are From the output it looks like webdev might be spawning 3 dart2js processes, one for each entrypoint. Am I interpreting that correctly? |
Thank you this is very valuable information.
Correct. Is this the regular CI job that you are concerned about? or are you also running tests with From the data above, the
|
We do have some larger packages on which we run tests in CI using We'd be more than happy to test out a custom dart2js to help get to the root of the problem! |
^ As some added context, in packages that we do run tests in CI, they are not run in parallel to the build step. We also tried another run where we only ran |
OK - that would explain why you are seeing ~20G earlier. Let us know if the tip from @jakemac53 to use
Awesome, thanks! |
I can confirm that using a reduced number of workers does help reduce the memory footprint. But it's not a silver bullet as it seems to increase the compilation time pretty dramatically on the package I tested it on. Here's what I'm seeing in CI as I vary
|
It sounds like separating out the building from the testing would be beneficial, that is what we do internally. You could run 4 separate jobs that each build one of the apps, and then a single job that runs the test using the built outputs from the other jobs. That would give you the fastest turnaround in terms of your CI and will ultimately scale the best as it will limit the amount of ram required for any individual job. |
Yeah we have already started moving tests to separate jobs, and we can split up the build steps in the case where we have multiple entry points, but it looks like we would still be interested in experimenting with a custom dart2js for the largest dart2js build step since it sustains a peak memory usage of 16-20GB even when run completely by itself. |
We have similar problems. If @evanweible-wf @todbachman-wf want to call, we can talk about some of our solutions to speed up.
|
@sigmundch How would we identify the offending code? |
Related #38797 |
@todbachman-wf - I have 2 changes I'd like you to try, even better if done separately. The changes are currently only in code reviews:
What's the best way for us to provide these changes to you? Do you need prebuilt binaries? Or by any chance do you have a setup to build the dart SDK, so a patch like the CL above would be enough for you to test things out? |
(Tod is on PTO for a couple days.) We don't currently have a CI setup that builds the dart SDK, so prebuilt binaries would be helpful, but we can also look into building from a CL. Do we need to be compatible with the latest dev channel of the SDK in order to use these dart2js refs? |
Thanks @evanweible-wf I'll look into what options we have available on our end as well (maybe we can give you a small snapshot of the compiler that could be copied into your sdk for testing, or maybe we have a channel that is frequent enough that we can ship this under a flag and let you test it out). If the former idea is an option, we should be able to rebase the code changes on top of the version of the sdk you are currently using. Can you remind me what version are you currently using? |
@sigmundch I verified that the latest on your == patch (https://dart-review.googlesource.com/c/sdk/+/123980) still shows the memory reduction to 15.4GB and reduced inference for == methods for us. |
Thanks! |
The flag is in megabytes. Try |
This just in: We started hitting the memory/page table limit in Linux on 2.4.1. setting both --old-gen-heap-size==30000000 and vm.max_map_count to 262144 on Dart 2.4.1 does in fact not crash where it used to. I feel like this should work on 2.6 as well if it weren't for the ceiling added in 13005ee |
@robbecker-wf I want to make sure that we are on the same page. You need to use |
@mraleph Yes, thank you. The double equals was a typo on my part (on github). I've also updated to MB instead of bytes. I can verify the effectiveness again if you think the flag would be ignored if too large? Currently using |
@robbecker-wf I was finally able to land the changes modeling The technique we use here could be extended one day to dynamically handle cases where the number of edges is too large. At this time, however, we only use the technique for When you have a chance, I'd be curious to see if adding some of the methods that you saw from the instrumented compile (like
|
@sigmundch Fantastic! Looks like we just missed the 2.6.0 release. I suppose this would make 2.6.1? |
Also, wow. That sure did escalate from basically a 1-liner fix. Thank you so much for putting in the effort to get this through! |
Correct, we would have missed the cut last week too given that we were already in the stabilization period. I submitted a merge request for the next stable release. Meanwhile, it should be visible in the next dev channel release.
Only that one line should be enough. We included |
I can confirm that |
Maybe in isolate.cc it is not actually using
|
@robbecker-wf you can't override heap limit for internal isolates used by the VM. this should not matter because dart2js compiler itself is running within main isolate. |
So, what I'm hearing is >= Dart 2.5 I can't use more than 16GB on Linux even if I have more than that in physical memory? |
@robbecker-wf that's not at all what I said - I would expect Do you have an exact error message you are getting? |
Sorry. Based on Ryan's comment #27883 (comment) and following discussion I was under the impression that setting the 2 settings would effectively give dart2js the ability to access more than 16GB. Here's the OOM error
|
@robbecker-wf - I wonder how you are providing the heap arguments when using webdev. I ask because I believe webdev is launching subprocesses internally, so those flags need to be plumb through all the way. I'm not as familiar with the configuration with webdev so I'm not sure if they expose a way to provide the flags in your configuration files or if more work is needed. |
That's a good point. In our Dockerfile I just added a I have noticed that the --print-metrics only seem to print one block vs many blocks of info when running dart2js directly .. so maybe those aren't getting passed into dart2js. Trying pbr and dart2js directly.. will report back. |
That did it. Apparently the DART_VM_OPTIONS do not tunnel through to internal processes. I ran dart2js directly and was able to compile the app on Linux in CI using Dart 2.6. It's not as convenient but it works. |
Yes, I've created one at https://github.com/dart-lang/webdev/issues/814. I asked @jakemac53 and he doesn't believe this is currently supported yet. |
🍾 This issue can finally be closed now that the fixes in #40217 have been merged and released as 2.7.1 |
Woo hoo! |
No, peak RSS is still 890MB. |
Can you give more details @rmacnak-google ? What's peak RSS? |
I am no longer able to build the SDK on my DragonBoard (a 1GB ARM64 board) because dart2js runs out of memory while compiling the Observatory.
The text was updated successfully, but these errors were encountered: