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
Collect eval memory before building with nix-build #5747
base: master
Are you sure you want to change the base?
Conversation
andir
commented
Dec 8, 2021
This made it easier for me to manuall track the lifetime of some of the variabes involved in the code.
This ensures that we free some of the memory that was allocated during the eval of the build target. In particular this will free the Boehm GC managed memory allocations. On my sample system I was able to reduce the memory consumption from 550MiB to about 200MiB when building the NixOS GNOME test. The memory did initially climb to 550MiB and then shrink down to 200MiB once the builds were kicked off. This means I can now run more build processes (without having to resort to swap) on resource constrained systems. Fixes NixOS#5200 (for me)
It would be nice to have some numbers on the performance cost. Doing a GC slows down I'm also concerned with doing the GC 10 times, which seems strange. I wouldn't expect a mark-and-sweep collector to free more memory on subsequent runs. The main risk here is that if there is any (false) pointer that keeps the BTW, as a workaround, you can use |
I do agree. I just went by what was in some of the related BoehmGC discussions and documentation. IIRC I tried with just one GC run and that wasn't sufficient to see a difference when I original tested this (~6M ago).
But then that is a bug that has to be fixed. It wouldn't surface right now because we don't care about the memory. We probably should care about the memory and fix the issues once we observe them.
Apparently it does so anyway.
I know. We discussed this in #5200. I dont' think that is a valid workaround for regular uses that just want to call |
Here are the results of some basic build testing. I've built the attribute before running the test. There were no actual builds performed during the testing. "new" is at commit ba655d46171b9eae5d5a3c54e47a0d13c0861ac6 The nixpkgs checkout was a2e281f5770247855b85d70c43454ba5bff34613.
It is indeed slower. Personally I'd prefer correctness (no leaked memory, system can reclaim space) over a fraction of a second in interactive evals. |
Could this be racy when garbage collection is used? |
@@ -570,8 +579,21 @@ static void main_nix_build(int argc, char * * argv) | |||
else | |||
drvMap[drvPath] = {drvMap.size(), {outputName}}; | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we do the evaluation in a child process and reclaim the memory this way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this option was discussed but dismissed.
Yes, if you want to do it right you have to do |
Since these GC run aren’t (hopefully) changing anything to the semantics of the program, could it make sense to start them in a different thread while the build is starting? That way the speed impact would be minimal |
Some possible mitigations for the performance cost: Regardless of this GC may still incur a cost by increasing utilization of the memory bus, which may very well be the bottleneck of a build process, so (a) is not a complete fix, but (b) is a "complete" if the system has plenty of memory.
Some things to make sure
|