DEV Community

Nitin Bansal
Nitin Bansal

Posted on

The very useful runtime package in golang 🏎🏎🏎

#go

runtime is a useful package that allows a programmer to control the behavior of runtime. It has many useful capabilities. A few of these that might be easily relatable are:

  1. runtime.Goexit(): To exit goroutine prematurely. It runs all deferred calls before terminating the goroutine. Also, this is not a panic. Calling Goexit from the main goroutine terminates that goroutine without func main returning. Since func main has not returned, the program continues execution of other goroutines. If all other goroutines exit, the program crashes.
  2. runtime.Gosched() => Yields the processor, allowing other goroutines to run. It does not suspend the current goroutine, so execution resumes automatically. This is like the keyword yield in other programming languaes like nodejs and python.
  3. runtime.GC(): Runs a garbage collection and blocks the caller until the garbage collection is complete. It may also block the entire program.
  4. runtime.KeepAlive(): Marks its argument as currently reachable. This ensures that the object is not freed, and its finalizer is not run, before the point in the program where KeepAlive is called. See example in official docs: https://pkg.go.dev/runtime#KeepAlive
  5. runtime.SetFinalizer(): Allows associating a callback function with an object that gets invoked once the object becomes unreachable. This callback runs in a separate goroutine and this current association is cleared. This also makes this object reachable once again, and the same object is eligible for garbage collection in next GC run. The object must be a pointer though. There is no guarantee that finalizers will run before a program exits, so typically they are useful only for releasing non-memory resources associated with an object during a long-running program. It is not guaranteed that a finalizer will run for objects allocated in initializers for package-level variables. Such objects may be linker-allocated, not heap-allocated. A single goroutine runs all finalizers for a program, sequentially. If a finalizer must run for a long time, it should do so by starting a new goroutine.
  6. runtime.LockOSThread(): Wires the calling goroutine to its current operating system thread. The calling goroutine will always execute in that thread, and no other goroutine will execute in it, until the calling goroutine has made as many calls to UnlockOSThread as to LockOSThread. If the calling goroutine exits without unlocking the thread, the thread will be terminated. This is useful to maintain ThreadLocal like state like used by libraries such as Cocoa, OpenGL, libSDL.
  7. runtime.NumCPU(): You must be familiar with this one. It returns the number of logical CPUs usable by the current process. This is used to set the value for GOMAXPROCS like runtime.GOMAXPROCS(runtime.NumCPU()). Note however that Starting from Go 1.5, the default value is the number of cores. You only need to explicitly set it if you are not okay with this in newer Go versions. Earlier this used to be just 1.
  8. runtime.ReadMemStats(): Very useful for diagnosis around memory issues. Gives detailed picture on how memory is being allocated, used, freed, and GC'ed. Here is a simple sample code demonstrating it's usage: https://gist.github.com/freakynit/116363b6768c15c50c1d6ff8faee03d0

That's all for now folks. Will add more to it as I discover... Enjoy..

Top comments (0)