123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- // Copyright 2013 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package debug
- import (
- "runtime"
- "sort"
- "time"
- )
- // GCStats collect information about recent garbage collections.
- type GCStats struct {
- LastGC time.Time // time of last collection
- NumGC int64 // number of garbage collections
- PauseTotal time.Duration // total pause for all collections
- Pause []time.Duration // pause history, most recent first
- PauseQuantiles []time.Duration
- }
- // Implemented in package runtime.
- func readGCStats(*[]time.Duration)
- func enableGC(bool) bool
- func setGCPercent(int) int
- func freeOSMemory()
- func setMaxStack(int) int
- func setMaxThreads(int) int
- // ReadGCStats reads statistics about garbage collection into stats.
- // The number of entries in the pause history is system-dependent;
- // stats.Pause slice will be reused if large enough, reallocated otherwise.
- // ReadGCStats may use the full capacity of the stats.Pause slice.
- // If stats.PauseQuantiles is non-empty, ReadGCStats fills it with quantiles
- // summarizing the distribution of pause time. For example, if
- // len(stats.PauseQuantiles) is 5, it will be filled with the minimum,
- // 25%, 50%, 75%, and maximum pause times.
- func ReadGCStats(stats *GCStats) {
- // Create a buffer with space for at least two copies of the
- // pause history tracked by the runtime. One will be returned
- // to the caller and the other will be used as a temporary buffer
- // for computing quantiles.
- const maxPause = len(((*runtime.MemStats)(nil)).PauseNs)
- if cap(stats.Pause) < 2*maxPause {
- stats.Pause = make([]time.Duration, 2*maxPause)
- }
- // readGCStats fills in the pause history (up to maxPause entries)
- // and then three more: Unix ns time of last GC, number of GC,
- // and total pause time in nanoseconds. Here we depend on the
- // fact that time.Duration's native unit is nanoseconds, so the
- // pauses and the total pause time do not need any conversion.
- readGCStats(&stats.Pause)
- n := len(stats.Pause) - 3
- stats.LastGC = time.Unix(0, int64(stats.Pause[n]))
- stats.NumGC = int64(stats.Pause[n+1])
- stats.PauseTotal = stats.Pause[n+2]
- stats.Pause = stats.Pause[:n]
- if len(stats.PauseQuantiles) > 0 {
- if n == 0 {
- for i := range stats.PauseQuantiles {
- stats.PauseQuantiles[i] = 0
- }
- } else {
- // There's room for a second copy of the data in stats.Pause.
- // See the allocation at the top of the function.
- sorted := stats.Pause[n : n+n]
- copy(sorted, stats.Pause)
- sort.Sort(byDuration(sorted))
- nq := len(stats.PauseQuantiles) - 1
- for i := 0; i < nq; i++ {
- stats.PauseQuantiles[i] = sorted[len(sorted)*i/nq]
- }
- stats.PauseQuantiles[nq] = sorted[len(sorted)-1]
- }
- }
- }
- type byDuration []time.Duration
- func (x byDuration) Len() int { return len(x) }
- func (x byDuration) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
- func (x byDuration) Less(i, j int) bool { return x[i] < x[j] }
- // SetGCPercent sets the garbage collection target percentage:
- // a collection is triggered when the ratio of freshly allocated data
- // to live data remaining after the previous collection reaches this percentage.
- // SetGCPercent returns the previous setting.
- // The initial setting is the value of the GOGC environment variable
- // at startup, or 100 if the variable is not set.
- // A negative percentage disables garbage collection.
- func SetGCPercent(percent int) int {
- old := setGCPercent(percent)
- runtime.GC()
- return old
- }
- // FreeOSMemory forces a garbage collection followed by an
- // attempt to return as much memory to the operating system
- // as possible. (Even if this is not called, the runtime gradually
- // returns memory to the operating system in a background task.)
- func FreeOSMemory() {
- freeOSMemory()
- }
- // SetMaxStack sets the maximum amount of memory that
- // can be used by a single goroutine stack.
- // If any goroutine exceeds this limit while growing its stack,
- // the program crashes.
- // SetMaxStack returns the previous setting.
- // The initial setting is 1 GB on 64-bit systems, 250 MB on 32-bit systems.
- //
- // SetMaxStack is useful mainly for limiting the damage done by
- // goroutines that enter an infinite recursion. It only limits future
- // stack growth.
- func SetMaxStack(bytes int) int {
- return setMaxStack(bytes)
- }
- // SetMaxThreads sets the maximum number of operating system
- // threads that the Go program can use. If it attempts to use more than
- // this many, the program crashes.
- // SetMaxThreads returns the previous setting.
- // The initial setting is 10,000 threads.
- //
- // The limit controls the number of operating system threads, not the number
- // of goroutines. A Go program creates a new thread only when a goroutine
- // is ready to run but all the existing threads are blocked in system calls, cgo calls,
- // or are locked to other goroutines due to use of runtime.LockOSThread.
- //
- // SetMaxThreads is useful mainly for limiting the damage done by
- // programs that create an unbounded number of threads. The idea is
- // to take down the program before it takes down the operating system.
- func SetMaxThreads(threads int) int {
- return setMaxThreads(threads)
- }
- // SetPanicOnFault controls the runtime's behavior when a program faults
- // at an unexpected (non-nil) address. Such faults are typically caused by
- // bugs such as runtime memory corruption, so the default response is to crash
- // the program. Programs working with memory-mapped files or unsafe
- // manipulation of memory may cause faults at non-nil addresses in less
- // dramatic situations; SetPanicOnFault allows such programs to request
- // that the runtime trigger only a panic, not a crash.
- // SetPanicOnFault applies only to the current goroutine.
- // It returns the previous setting.
- func SetPanicOnFault(enabled bool) bool
- // WriteHeapDump writes a description of the heap and the objects in
- // it to the given file descriptor.
- // The heap dump format is defined at http://golang.org/s/go13heapdump.
- func WriteHeapDump(fd uintptr)
|