github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/runtime/debug/garbage.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package debug 6 7 import ( 8 "runtime" 9 "sort" 10 "time" 11 ) 12 13 // GCStats collect information about recent garbage collections. 14 type GCStats struct { 15 LastGC time.Time // time of last collection 16 NumGC int64 // number of garbage collections 17 PauseTotal time.Duration // total pause for all collections 18 Pause []time.Duration // pause history, most recent first 19 PauseQuantiles []time.Duration 20 } 21 22 // Implemented in package runtime. 23 func readGCStats(*[]time.Duration) 24 func enableGC(bool) bool 25 func setGCPercent(int) int 26 func freeOSMemory() 27 28 // ReadGCStats reads statistics about garbage collection into stats. 29 // The number of entries in the pause history is system-dependent; 30 // stats.Pause slice will be reused if large enough, reallocated otherwise. 31 // ReadGCStats may use the full capacity of the stats.Pause slice. 32 // If stats.PauseQuantiles is non-empty, ReadGCStats fills it with quantiles 33 // summarizing the distribution of pause time. For example, if 34 // len(stats.PauseQuantiles) is 5, it will be filled with the minimum, 35 // 25%, 50%, 75%, and maximum pause times. 36 func ReadGCStats(stats *GCStats) { 37 // Create a buffer with space for at least two copies of the 38 // pause history tracked by the runtime. One will be returned 39 // to the caller and the other will be used as a temporary buffer 40 // for computing quantiles. 41 const maxPause = len(((*runtime.MemStats)(nil)).PauseNs) 42 if cap(stats.Pause) < 2*maxPause { 43 stats.Pause = make([]time.Duration, 2*maxPause) 44 } 45 46 // readGCStats fills in the pause history (up to maxPause entries) 47 // and then three more: Unix ns time of last GC, number of GC, 48 // and total pause time in nanoseconds. Here we depend on the 49 // fact that time.Duration's native unit is nanoseconds, so the 50 // pauses and the total pause time do not need any conversion. 51 readGCStats(&stats.Pause) 52 n := len(stats.Pause) - 3 53 stats.LastGC = time.Unix(0, int64(stats.Pause[n])) 54 stats.NumGC = int64(stats.Pause[n+1]) 55 stats.PauseTotal = stats.Pause[n+2] 56 stats.Pause = stats.Pause[:n] 57 58 if len(stats.PauseQuantiles) > 0 { 59 if n == 0 { 60 for i := range stats.PauseQuantiles { 61 stats.PauseQuantiles[i] = 0 62 } 63 } else { 64 // There's room for a second copy of the data in stats.Pause. 65 // See the allocation at the top of the function. 66 sorted := stats.Pause[n : n+n] 67 copy(sorted, stats.Pause) 68 sort.Sort(byDuration(sorted)) 69 nq := len(stats.PauseQuantiles) - 1 70 for i := 0; i < nq; i++ { 71 stats.PauseQuantiles[i] = sorted[len(sorted)*i/nq] 72 } 73 stats.PauseQuantiles[nq] = sorted[len(sorted)-1] 74 } 75 } 76 } 77 78 type byDuration []time.Duration 79 80 func (x byDuration) Len() int { return len(x) } 81 func (x byDuration) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 82 func (x byDuration) Less(i, j int) bool { return x[i] < x[j] } 83 84 // SetGCPercent sets the garbage collection target percentage: 85 // a collection is triggered when the ratio of freshly allocated data 86 // to live data remaining after the previous collection reaches this percentage. 87 // SetGCPercent returns the previous setting. 88 // The initial setting is the value of the GOGC environment variable 89 // at startup, or 100 if the variable is not set. 90 // A negative percentage disables garbage collection. 91 func SetGCPercent(percent int) int { 92 return setGCPercent(percent) 93 } 94 95 // FreeOSMemory forces a garbage collection followed by an 96 // attempt to return as much memory to the operating system 97 // as possible. (Even if this is not called, the runtime gradually 98 // returns memory to the operating system in a background task.) 99 func FreeOSMemory() { 100 freeOSMemory() 101 }