mirror of
				https://github.com/golang/go.git
				synced 2025-10-31 00:30:57 +00:00 
			
		
		
		
	runtime: recheck GC trigger before actually starting GC
Currently allocation checks the GC trigger speculatively during allocation and then triggers the GC without rechecking. As a result, it's possible for G 1 and G 2 to detect the trigger simultaneously, both enter startGC, G 1 actually starts GC while G 2 gets preempted until after the whole GC cycle, then G 2 immediately starts another GC cycle even though the heap is now well under the trigger. Fix this by re-checking the GC trigger non-speculatively just before actually kicking off a new GC cycle. This contributes to #11911 because when this happens, we definitely don't finish the background sweep before starting the next GC cycle, which can significantly delay the start of concurrent scan. Change-Id: I560ab79ba5684ba435084410a9765d28f5745976 Reviewed-on: https://go-review.googlesource.com/13025 Reviewed-by: Russ Cox <rsc@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
This commit is contained in:
		
							parent
							
								
									d5f5e658ae
								
							
						
					
					
						commit
						88e945fd23
					
				
					 1 changed files with 8 additions and 0 deletions
				
			
		|  | @ -841,6 +841,14 @@ func startGC(mode int) { | |||
| 	// trigger concurrent GC | ||||
| 	readied := false | ||||
| 	lock(&bggc.lock) | ||||
| 	// The trigger was originally checked speculatively, so | ||||
| 	// recheck that this really should trigger GC. (For example, | ||||
| 	// we may have gone through a whole GC cycle since the | ||||
| 	// speculative check.) | ||||
| 	if !shouldtriggergc() { | ||||
| 		unlock(&bggc.lock) | ||||
| 		return | ||||
| 	} | ||||
| 	if !bggc.started { | ||||
| 		bggc.working = 1 | ||||
| 		bggc.started = true | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Austin Clements
						Austin Clements