Runtime Goroutine Management — Specification¶
This file collects the documented signatures, semantics, and guarantees for each runtime API discussed in this subsection. It is a reference, not a tutorial. Quoted text is paraphrased from the Go standard-library documentation (Go 1.22+). Verify behaviour against your target Go version.
Table of Contents¶
- Package
runtime - Package
runtime/debug - Package
runtime/pprof - Package
runtime/trace - Package
runtime/metrics - Environment Variables
- Defaults Table
Package runtime¶
func NumGoroutine() int¶
Returns the number of goroutines that currently exist. The count includes the main goroutine, user-spawned goroutines, and runtime-internal goroutines (GC workers, finalizer goroutine, optional trace goroutine).
Concurrency: safe to call from any goroutine. Cost: O(1) atomic read.
func NumCPU() int¶
Returns the number of logical CPUs usable by the current process. The set of available CPUs is determined at program startup and is not updated for process affinity changes during execution.
func GOMAXPROCS(n int) int¶
Sets the maximum number of CPUs that can execute Go code simultaneously and returns the previous setting. If n < 1, it does not change the current setting.
When n differs from the current value, the runtime stops the world to resize the P array.
func Gosched()¶
Yields the processor, allowing other goroutines to run. It does not suspend the current goroutine; execution resumes automatically.
The yielding goroutine is placed on the global runqueue, making it available for any P to pick up.
func Goexit()¶
Terminates the goroutine that calls it. No other goroutine is affected. Goexit runs all deferred calls before terminating the goroutine. Because Goexit is not a panic, any deferred recover() calls in those deferred functions will return nil.
Calling Goexit from the main goroutine terminates that goroutine without main returning. Because main has not returned, the program continues execution of other goroutines. If all other goroutines exit, the program crashes.
func LockOSThread()¶
Wires the calling goroutine to its current operating-system thread. The goroutine will always execute on that thread, and no other goroutine will execute on it, until the calling goroutine calls UnlockOSThread the same number of times. If the calling goroutine exits without unlocking, the thread will be terminated.
All init functions in a Go program run on the main goroutine, which is also the first goroutine to which LockOSThread is automatically applied when init runs.
LockOSThread is re-entrant since Go 1.10. Lock and unlock counts must match.
func UnlockOSThread()¶
Undoes one call to LockOSThread. Calls in excess of LockOSThread calls are silently ignored.
func Stack(buf []byte, all bool) int¶
Formats a stack trace of the calling goroutine into buf and returns the number of bytes written. If all is true, formats stack traces of all other goroutines into buf after the trace of the current goroutine.
When all=true the runtime stops the world for the duration of the call.
func SetFinalizer(obj any, finalizer any)¶
Sets the finalizer associated with obj to the provided function. When the garbage collector finds an unreachable block with a finalizer, it clears the association and runs finalizer(obj) in a separate goroutine. The block is reclaimed only on the next GC cycle.
Requirements: - obj must be a non-nil pointer or unsafe.Pointer. - obj must have been allocated by Go (e.g. new, make, composite literal). Setting finalizers on stack-allocated or non-Go-allocated pointers is undefined behaviour. - finalizer must be a function whose first parameter is assignable from the type of obj, or nil.
To remove a finalizer, call SetFinalizer(obj, nil).
A finalizer is not guaranteed to run. The runtime may skip them at program exit. Order of finalization is unspecified.
func SetMutexProfileFraction(rate int) int¶
Controls the fraction of mutex contention events that are reported in the mutex profile. On average, one event per rate is reported. Setting rate = 0 turns off profiling. The previous rate is returned. Cost: each contention event probabilistically samples; lower rate = higher sampling = higher overhead.
func SetBlockProfileFraction(rate int) int¶
Controls the fraction of goroutine blocking events that are reported. A blocking event is reported with probability proportional to blocked-time / rate (in nanoseconds). Setting rate = 0 turns off profiling. Setting rate = 1 records every event.
func GC()¶
Runs a garbage collection and blocks the caller until the collection is complete. May also block the entire program.
Use only in tests, benchmarks, or rare circumstances where you can prove a forced GC is necessary.
func SetCgoTraceback(version int, traceback, context, symbolizer unsafe.Pointer)¶
Registers callbacks the runtime uses to construct stack traces that include C frames. version must be 0 in current Go.
Package runtime/debug¶
func Stack() []byte¶
Returns a formatted stack trace of the calling goroutine. Equivalent to runtime.Stack(buf, false) with sufficient buffer.
func PrintStack()¶
Prints a formatted stack trace of the calling goroutine to standard error.
func SetGCPercent(percent int) int¶
Sets the garbage collection target percentage. A collection is triggered when the ratio of newly allocated data to live data at the previous collection reaches this percentage. The previous setting is returned.
SetGCPercent(-1) disables garbage collection (except via the memory limit). Returns the previous percent. Cost: takes effect at next allocation.
func SetMemoryLimit(limit int64) int64¶
(Added in Go 1.19.) Provides a soft memory limit for the runtime. The runtime undertakes whatever measures it can to keep memory usage under this limit, including running garbage collection more frequently and returning memory to the OS more aggressively.
A negative limit is taken to mean "no change." The previous value is returned. SetMemoryLimit(math.MaxInt64) effectively removes the limit.
The limit is a target, not a guarantee. The runtime will not stop user code mid-allocation to enforce it.
func SetMaxStack(bytes int) int¶
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.
Default: ~1 GB on 64-bit, ~250 MB on 32-bit. Useful for crashing earlier on infinite recursion.
func SetMaxThreads(threads int) int¶
Sets the maximum number of operating system threads the Go program can use. If exceeded, the program crashes by calling exit(2).
Default: 10 000. Set lower as a safety net against thread-creation storms (cgo, syscall surges).
func SetTraceback(level string)¶
Sets the amount of detail printed by the runtime on a fatal panic or unhandled signal. Valid levels (most to least verbose): crash, system, all, single, none. Default is single.
Equivalent to the GOTRACEBACK environment variable.
func SetPanicOnFault(enabled bool) bool¶
Controls the runtime's behaviour when a program faults at an unexpected (non-nil) address. Such faults are normally unrecoverable. With SetPanicOnFault(true), they become recoverable via recover() in the goroutine that faulted. Used by mmap users who want to handle SIGSEGV gracefully.
func FreeOSMemory()¶
Forces a garbage collection followed by an attempt to return as much memory as possible to the operating system. Even if not called, the runtime gradually returns memory to the OS in the background.
func ReadGCStats(stats *GCStats)¶
Reads statistics about recent garbage collections into *stats. Includes pause times, number of cycles, and other historical data.
Package runtime/pprof¶
type LabelSet¶
An opaque set of label key/value pairs. Constructed via pprof.Labels.
func Labels(args ...string) LabelSet¶
Returns a LabelSet with the provided key/value pairs. Panics if called with an odd number of arguments.
func WithLabels(ctx context.Context, labels LabelSet) context.Context¶
Returns a context derived from ctx with the labels added. Labels from ctx are merged with labels; conflicting keys are overwritten.
func SetGoroutineLabels(ctx context.Context)¶
Sets the labels of the current goroutine to those in ctx. The previous labels are replaced, not merged.
func Do(ctx context.Context, labels LabelSet, f func(context.Context))¶
Calls f with a context derived from ctx and the merged labels. Sets the calling goroutine's labels for the duration of f's execution, then restores them.
func ForLabels(ctx context.Context, f func(key, value string) bool)¶
Invokes f for each label in ctx. Stops if f returns false.
func Lookup(name string) *Profile¶
Returns the named profile ("goroutine", "heap", "allocs", "threadcreate", "block", "mutex").
func StartCPUProfile(w io.Writer) error¶
Starts CPU profiling, writing samples to w. Returns an error if profiling is already active.
func StopCPUProfile()¶
Stops CPU profiling. Must be called before the program exits to flush remaining samples.
Package runtime/trace¶
func Start(w io.Writer) error¶
Begins recording trace events to w. Returns an error if a trace is already in progress.
func Stop()¶
Stops the current trace.
func NewTask(ctx context.Context, taskType string) (context.Context, *Task)¶
Creates a logical task. The returned context carries the task. Call task.End() when the task completes.
func WithRegion(ctx context.Context, regionType string, f func())¶
Marks a section of code as a "region" within a task. Useful for breaking down task latency.
func Log(ctx context.Context, category, message string)¶
Emits a log message in the trace.
func IsEnabled() bool¶
Reports whether tracing is currently active.
Package runtime/metrics¶
type Description¶
Describes a metric: its name, a textual description, its kind, and whether it is cumulative.
type Sample¶
A Sample is a (name, value) pair. The caller sets Name; the runtime fills Value on Read.
type Value¶
A tagged union. Methods: Kind() ValueKind, Uint64() uint64, Float64() float64, Float64Histogram() *Float64Histogram.
ValueKind is one of KindBad, KindUint64, KindFloat64, KindFloat64Histogram.
type Float64Histogram¶
Has Counts []uint64 and Buckets []float64. The ith bucket has count Counts[i] and range [Buckets[i], Buckets[i+1]).
func All() []Description¶
Returns descriptions of all metrics exported by the running Go version.
func Read(samples []Sample)¶
Populates each samples[i].Value with the current value of the named metric.
Standard metric names (selected)¶
/sched/goroutines:goroutines— count of live goroutines./sched/latencies:seconds— histogram of scheduler latencies./memory/classes/heap/objects:bytes— live heap./memory/classes/heap/free:bytes— free heap memory./memory/classes/total:bytes— total memory the runtime accounts for./gc/pauses:seconds— histogram of GC STW pause durations./gc/cycles/total:gc-cycles— total completed GC cycles./gc/heap/allocs:bytes— cumulative bytes allocated./cpu/classes/gc/total:cpu-seconds— cumulative GC CPU time./cpu/classes/user/total:cpu-seconds— cumulative user-code CPU time.
The full set is discovered at runtime via metrics.All().
Environment Variables¶
| Variable | Effect |
|---|---|
GOMAXPROCS | Initial GOMAXPROCS value. |
GOGC | Initial GOGC value. Default 100. off disables GC. |
GOMEMLIMIT | Initial memory limit. Default math.MaxInt64. Accepts suffixes: MiB, GiB, etc. |
GOTRACEBACK | Verbosity of panic stack dumps. none, single, all, system, crash. |
GODEBUG | Runtime debug knobs. See GODEBUG runtime for the full catalog. |
GOROOT, GOPATH, GOPROXY, etc. | Build/runtime, not directly scheduler-related. |
Defaults Table¶
| Setting | Default |
|---|---|
GOMAXPROCS (pre-1.25) | runtime.NumCPU() |
GOMAXPROCS (1.25+) | max(1, ceil(cpu_quota)) if container, else NumCPU() |
GOGC | 100 |
GOMEMLIMIT | math.MaxInt64 (no limit) |
GOTRACEBACK | single |
debug.SetMaxStack | 1 GB on 64-bit, 250 MB on 32-bit |
debug.SetMaxThreads | 10 000 |
SetMutexProfileFraction | 0 (off) |
SetBlockProfileFraction | 0 (off) |
| Memory profile sampling rate | 1 sample per 512 KB allocated |
| CPU profile sampling rate | 100 Hz per OS thread |
| GC CPU usage cap | ~25% per CPU |
Guarantees and Non-Guarantees¶
Guaranteed¶
NumGoroutinereturns at least 1 while any Go code is running.Goexitruns all deferred functions before terminating its goroutine.- A
LockOSThread-locked goroutine that exits causes its OS thread to be destroyed (so thread-local state is not reused). SetMemoryLimitandSetGCPercentreturn the previous value.runtime/metricsmetric names and units are stable within a major Go version.
Not Guaranteed¶
- The exact thread/goroutine count under load.
- The latency of
Gosched(depends on runqueue state). - The order in which finalizers run.
- That finalizers run at all before program exit.
- The exact format of stack trace strings (may change between versions).
- The cost of
SetMemoryLimitin micro-pauses (depends on heap state). - Default values for environment variables — subject to change between Go versions.