From 570a292bab2ae73b3338c86cf5836606074adb39 Mon Sep 17 00:00:00 2001 From: Dan Willemsen Date: Tue, 26 May 2020 23:02:29 -0700 Subject: [PATCH] Better handling of low memory situations Drop down to a single high-mem task when we've got <=16GB, as the system probably isn't completely free RAM, ninja will be using a couple gigs, along with whatever "normal" actions will be running concurrently. So it's unlikely that we can handle two 6-8GB actions along with everything else. Also print warnings when we detect <=16GB total RAM, or when we're running more parallel jobs than than we have GB RAM. These both notify the user and suggest lowering the `-j` value if they run into problems. Test: fake totalRAM to [0.5,8,16]GB, checking warning Test: fake totalRAM to 17GB, `m -j4 nothing` has no warning Test: `m -j187 nothing` on a 188GB system Test: `m -j188 nothing` on a 188GB system Change-Id: Ieb008e9f462d5f40fb65781d94cf116b1caf8446 --- ui/build/build.go | 21 ++++++++++++++++++++- ui/build/config.go | 3 +++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ui/build/build.go b/ui/build/build.go index 112273345..89c3fad20 100644 --- a/ui/build/build.go +++ b/ui/build/build.go @@ -141,7 +141,26 @@ func help(ctx Context, config Config, what int) { func Build(ctx Context, config Config, what int) { ctx.Verboseln("Starting build with args:", config.Arguments()) ctx.Verboseln("Environment:", config.Environment().Environ()) - ctx.Verbosef("Total RAM: %dGB", config.TotalRAM()/1024/1024/1024) + + if totalRAM := config.TotalRAM(); totalRAM != 0 { + ram := float32(totalRAM) / (1024 * 1024 * 1024) + ctx.Verbosef("Total RAM: %.3vGB", ram) + + if ram <= 16 { + ctx.Println("************************************************************") + ctx.Printf("You are building on a machine with %.3vGB of RAM\n", ram) + ctx.Println("") + ctx.Println("The minimum required amount of free memory is around 16GB,") + ctx.Println("and even with that, some configurations may not work.") + ctx.Println("") + ctx.Println("If you run into segfaults or other errors, try reducing your") + ctx.Println("-j value.") + ctx.Println("************************************************************") + } else if ram <= float32(config.Parallel()) { + ctx.Printf("Warning: high -j%d count compared to %.3vGB of RAM", config.Parallel(), ram) + ctx.Println("If you run into segfaults or other errors, try a lower -j value") + } + } ctx.BeginTrace(metrics.Total, "total") defer ctx.EndTrace() diff --git a/ui/build/config.go b/ui/build/config.go index 7fcc47199..d66a86cb1 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -737,6 +737,9 @@ func (c *configImpl) HighmemParallel() int { } else if c.totalRAM == 0 { // Couldn't detect the total RAM, don't restrict highmem processes. return parallel + } else if c.totalRAM <= 16*1024*1024*1024 { + // Less than 16GB of ram, restrict to 1 highmem processes + return 1 } else if c.totalRAM <= 32*1024*1024*1024 { // Less than 32GB of ram, restrict to 2 highmem processes return 2