github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/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 func setMaxStack(int) int 28 func setMaxThreads(int) int 29 30 // ReadGCStats reads statistics about garbage collection into stats. 31 // The number of entries in the pause history is system-dependent; 32 // stats.Pause slice will be reused if large enough, reallocated otherwise. 33 // ReadGCStats may use the full capacity of the stats.Pause slice. 34 // If stats.PauseQuantiles is non-empty, ReadGCStats fills it with quantiles 35 // summarizing the distribution of pause time. For example, if 36 // len(stats.PauseQuantiles) is 5, it will be filled with the minimum, 37 // 25%, 50%, 75%, and maximum pause times. 38 func ReadGCStats(stats *GCStats) { 39 // Create a buffer with space for at least two copies of the 40 // pause history tracked by the runtime. One will be returned 41 // to the caller and the other will be used as a temporary buffer 42 // for computing quantiles. 43 const maxPause = len(((*runtime.MemStats)(nil)).PauseNs) 44 if cap(stats.Pause) < 2*maxPause { 45 stats.Pause = make([]time.Duration, 2*maxPause) 46 } 47 48 // readGCStats fills in the pause history (up to maxPause entries) 49 // and then three more: Unix ns time of last GC, number of GC, 50 // and total pause time in nanoseconds. Here we depend on the 51 // fact that time.Duration's native unit is nanoseconds, so the 52 // pauses and the total pause time do not need any conversion. 53 readGCStats(&stats.Pause) 54 n := len(stats.Pause) - 3 55 stats.LastGC = time.Unix(0, int64(stats.Pause[n])) 56 stats.NumGC = int64(stats.Pause[n+1]) 57 stats.PauseTotal = stats.Pause[n+2] 58 stats.Pause = stats.Pause[:n] 59 60 if len(stats.PauseQuantiles) > 0 { 61 if n == 0 { 62 for i := range stats.PauseQuantiles { 63 stats.PauseQuantiles[i] = 0 64 } 65 } else { 66 // There's room for a second copy of the data in stats.Pause. 67 // See the allocation at the top of the function. 68 sorted := stats.Pause[n : n+n] 69 copy(sorted, stats.Pause) 70 sort.Sort(byDuration(sorted)) 71 nq := len(stats.PauseQuantiles) - 1 72 for i := 0; i < nq; i++ { 73 stats.PauseQuantiles[i] = sorted[len(sorted)*i/nq] 74 } 75 stats.PauseQuantiles[nq] = sorted[len(sorted)-1] 76 } 77 } 78 } 79 80 type byDuration []time.Duration 81 82 func (x byDuration) Len() int { return len(x) } 83 func (x byDuration) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 84 func (x byDuration) Less(i, j int) bool { return x[i] < x[j] } 85 86 // SetGCPercent sets the garbage collection target percentage: 87 // a collection is triggered when the ratio of freshly allocated data 88 // to live data remaining after the previous collection reaches this percentage. 89 // SetGCPercent returns the previous setting. 90 // The initial setting is the value of the GOGC environment variable 91 // at startup, or 100 if the variable is not set. 92 // A negative percentage disables garbage collection. 93 func SetGCPercent(percent int) int { 94 return setGCPercent(percent) 95 } 96 97 // FreeOSMemory forces a garbage collection followed by an 98 // attempt to return as much memory to the operating system 99 // as possible. (Even if this is not called, the runtime gradually 100 // returns memory to the operating system in a background task.) 101 func FreeOSMemory() { 102 freeOSMemory() 103 } 104 105 // SetMaxStack sets the maximum amount of memory that 106 // can be used by a single goroutine stack. 107 // If any goroutine exceeds this limit while growing its stack, 108 // the program crashes. 109 // SetMaxStack returns the previous setting. 110 // The initial setting is 1 GB on 64-bit systems, 250 MB on 32-bit systems. 111 // 112 // SetMaxStack is useful mainly for limiting the damage done by 113 // goroutines that enter an infinite recursion. It only limits future 114 // stack growth. 115 func SetMaxStack(bytes int) int { 116 return setMaxStack(bytes) 117 } 118 119 // SetMaxThreads sets the maximum number of operating system 120 // threads that the Go program can use. If it attempts to use more than 121 // this many, the program crashes. 122 // SetMaxThreads returns the previous setting. 123 // The initial setting is 10,000 threads. 124 // 125 // The limit controls the number of operating system threads, not the number 126 // of goroutines. A Go program creates a new thread only when a goroutine 127 // is ready to run but all the existing threads are blocked in system calls, cgo calls, 128 // or are locked to other goroutines due to use of runtime.LockOSThread. 129 // 130 // SetMaxThreads is useful mainly for limiting the damage done by 131 // programs that create an unbounded number of threads. The idea is 132 // to take down the program before it takes down the operating system. 133 func SetMaxThreads(threads int) int { 134 return setMaxThreads(threads) 135 }