automemlimit

repository·main·Indexed 19 days ago

https://github.com/kimmachinegun/automemlimit

A Go library that automatically sets the GOMEMLIMIT environment variable to match memory limits imposed by Linux cgroups, helping to prevent OOM kills in containerized environments. It supports side-effect imports for zero-configuration setup, fine-grained control via the memlimit package, and optional fallback to system memory limits.

Tokens
1.2K
Snippets
5
Records
6
Agent score
18%

What's inside automemlimit

  1. Use system memory limits as a fallback

    main

    If cgroup limits are unavailable, you can use system memory limits. This can be done in two ways:

    1. Environment Variable: Set AUTOMEMLIMIT_EXPERIMENT=system to enable experimental fallback to system memory limits.
    2. Programmatically: Use memlimit.FromSystem as a provider, or use memlimit.ApplyFallback(memlimit.FromCgroup, memlimit.FromSystem) to attempt cgroup detection first and fall back to system limits if cgroups are not found.
  2. Use automemlimit with default settings

    main

    The simplest way to use automemlimit is to import it with a blank identifier. This automatically sets GOMEMLIMIT to 90% of the Linux cgroup memory limit and enables default logging. This is equivalent to calling memlimit.SetGoMemLimitWithOpts(memlimit.WithLogger(slog.Default())).

    package main
    
    import _ "github.com/KimMachineGun/automemlimit"
  3. Enable automatic GOMEMLIMIT via side-effect import

    main

    The automemlimit package provides a zero-configuration way to set the GOMEMLIMIT environment variable automatically by using a side-effect import. When you import the package, its init() function is executed, which calls memlimit.SetGoMemLimitWithOpts using the default slog logger. This is useful for applications that want to automatically adjust their memory limit based on the available system memory without manual configuration.

    import _ "github.com/KimMachineGun/automemlimit/automemlimit"
  4. Configure memory limits with alternative memlimit methods

    main

    The memlimit package provides several shorthand methods for setting the memory limit depending on your needs:

    package main
    
    import "github.com/KimMachineGun/automemlimit/memlimit"
    
    func init() {
    	// Set limit based on a ratio (e.g., 90%)
    	memlimit.SetGoMemLimit(0.9)
    
    	// Set limit with a specific provider and ratio
    	memlimit.SetGoMemLimitWithProvider(memlimit.FromCgroup, 0.9)
    
    	// Set limit with a hard limit value and a ratio
    	memlimit.SetGoMemLimitWithProvider(memlimit.Limit(1024*1024), 0.9)
    
    	// Specific Cgroup providers
    	memlimit.SetGoMemLimitWithProvider(memlimit.FromCgroupV1, 0.9)
    	memlimit.SetGoMemLimitWithProvider(memlimit.FromCgroupV2, 0.9)
    	memlimit.SetGoMemLimitWithProvider(memlimit.FromCgroupHybrid, 0.9)
    }
  5. Configure memory limits with memlimit.SetGoMemLimitWithOpts

    main

    For fine-grained control, use the memlimit package. You can configure the memory limit ratio, the provider (where the limit is sourced from), logging, and how often the limit is refreshed.

    package main
    
    import "github.com/KimMachineGun/automemlimit/memlimit"
    import "log/slog"
    import "time"
    
    func init() {
    	// Example: Custom configuration with ratio, provider, logger, and refresh interval
    	memlimit.SetGoMemLimitWithOpts(
    		memlimit.WithRatio(0.9),
    		memlimit.WithProvider(memlimit.FromCgroup),
    		memlimit.WithLogger(slog.Default()),
    		memlimit.WithRefreshInterval(1*time.Minute),
    	)
    
    	// Example: Using a fallback provider (Cgroup with System fallback)
    	memlimit.SetGoMemLimitWithOpts(
    		memlimit.WithRatio(0.9),
    		memlimit.WithProvider(
    			memlimit.ApplyFallback(
    				memlimit.FromCgroup,
    				memlimit.FromSystem,
    			),
    		),
    		memlimit.WithRefreshInterval(1*time.Minute),
    	)
    }