Showing posts with label golang_gc. Show all posts
Showing posts with label golang_gc. Show all posts

Feb 9, 2021

[Go] Continuous memory allocation

Reference: allocate Nodes together with Name/Param/Func


Continuous memory allocation is always a thing.

Go example:

var x struct {
    n Node
    m Name
    p Param
}
n := &x.n
n.Name = &x.m
n.Name.Param = &x.p

instead of writing:
n := &Node {
    Name: &Name {
        Param: &Param{},
    }}

Sep 29, 2020

[Go] memory allocation

Memory allocation:

1. <32KB, from local cache mcache's mspan for each P
Those mspan has 70 different sizes, from 8 bytes to 32k bytes
Each size has 2 mspan, one for object contains pointers, one
for object contains no pointers(for GC purpose design)

While local mcache is all used, there's mcentral cache.
Each size in mcentral contains 2 list, non-empty and empty list.
By empty means all memory slots are used.

The basic unit is mspan. Thus local cache shall borrow 1 mspan
from mcentral if local cache is all used.

If memory in mcentral were all used, allocates heap memory from
mheap to mcentral.

mheap is chunked with arena(s), arena is mapped with virtual memory pages.
mspan is allotted from arena.


2. >32KB are rounded up to page size directly allotted from mheap


This design idea is from Google's TCMalloc library.




[Go] GC spec

  1. under 4MB memory consumption GC will not be triggered
  2. between 2 garbage collecting more than 2 minutes, 1 GC cycle will be triggered.
  3. heap threshold being reached GC will be triggered (100% memory bump) (env variable  GOGC set to 100)
  4. Go garbage collector is to not take more than 25% of the CPU.
    i.e will use goroutine that is in idle queue to do the GC marking phase while the total counts of goroutine, which uses a P, is less than total counts of P.


Jun 26, 2020

[Go] allocation costs on latency (Go 1.15)

Reference:

In the current implementation, on the slow path, it looks through a
limited number of spans to find one that has space, and then it sweeps
that one and uses it.

It checks up to 100 spans looking for one to sweep; if it doesn't find any in the first 100 that it checks, it allocates a new span. So, there is an upper bound on allocation time.

Mar 5, 2019

[Go] Garbage collector recycle steps in golang

Tri-Color GC Steps:
The garbage collector assigns objects to three sets:
black, grey, and white.

https://making.pusher.com/golangs-real-time-gc-in-theory-and-practice/

Concurrent GC can yield lower latencies for large heap sizes, which better then a stop-the-world collector.
  • One of the costs is reduced throughput.
    • Obviously, concurrency requires extra work for synchronization and duplication.
  • Another cost of concurrent GC is unpredictable heap growth.

Reference:
Go 1.5 concurrent garbage collector pacing - Austin Clements

Proposal: Eliminate STW stack re-scanning - Austin Clements

Golang’s Real-time GC in Theory and Practice

Jan 27, 2019

[Go] Getting to Go: The Journey of Go's Garbage Collector - note

Reference:
Getting to Go: The Journey of Go's Garbage Collector
Go GC: Latency Problem Solved


Like C++, Go is a value-oriented language.
Why? Since it's easy to access C/C++ function interface.

Beware, while Golang is a GC language,
any reference to type's data member can prolong
the live of the type instance.
In Golang, they call it 'interior pointers'.
Such pointers keep the entire value(i.e type's instance in C++'s jargon)
live and they are fairly common.

Golang's elf binary contains the whole Golang Runtime.
i.e No more JIT recompilation.
Pro
    Reproducibility of program execution is a lot easier which makes moving forward with compiler improvements much faster.

Con
    Don't have the chance to do feedback optimizations as you would with a JITed system.
 
 

Knobs to control the GC

  • GCPercent
    A knob that adjusts how much CPU you want to use and how much memory you want to use.
  • MaxHeap
    Set what the maximum heap size should be.
    Temporary spikes in memory usage should be handled by increasing CPU costs, not by aborting.


     

Why is latency so important?


 

Fight the tyranny of the 9s(99.99%) with redundancy

But~
Redundancy wasn't going to scale, redundancy costs a lot.



Abbr

  • service level objective (SLO)
  • Stop-the-world (STW)



Tri-color concurrent algorithm



Size segregated spans been introduced and it has some other advantages

Reference:
[golang] Golang's memory management - Eben Freeman [note]
  • Low fragmentation
  • Internal structures
  • Speed

 

Object's metadata

We needed to have some information about the objects since we didn't have headers.
Mark bits are kept on the side and used for marking as well as allocation.

Each word has 2 bits associated with it to tell you if it was a scalar or a pointer inside that word.

It also encoded whether there were more pointers in the object so we could stop scanning objects sooner than later.

We also had an extra bit encoding that we could use as an extra mark bit or to do other debugging things.
This design is valuable for getting this stuff running and finding bugs.



Write barriers

The write barrier is 'on' only during the GC.



GC Pacer

When to best start a GC cycle.

At a high level the Pacer stops the Goroutine, which is doing a lot of the allocation, and puts it to work doing marking.

If the system is in a steady state and not in a phase change, marking will end just about the time memory runs out.

The amount of work is proportional to the Goroutine's allocation. This speeds up the garbage collector while slowing down the mutator.

When all of this is done the Pacer takes what it has learnt from this GC cycle as well as previous ones and projects when to start the next GC.

Reference:
[Design Doc] Go 1.5 concurrent garbage collector pacing
[Proposal] Proposal: Separate soft and hard heap size goal


With the failure experience of which types of GC to adopt,
Escape analysis and Value-orientation succeed.



Card marking without a write barrier

Maintain a hash of mature pointers in each card. If pointers are written into a card, the hash will change and the card will be considered marked. This would trade the cost of write barrier off for cost of hashing.

Today's modern architectures have AES (Advanced Encryption Standard) instructions.
One of those instructions can do encryption-grade hashing and with encryption-grade hashing we don't have to worry about collisions if we also follow standard encryption policies. So hashing is not going to cost us much but we have to load up what we are going to hash.

Reference:
https://mattwarren.org/2016/02/04/learning-how-garbage-collectors-work-part-1
http://factor-language.blogspot.com/2008/05/garbage-collection-throughput.html
https://blogs.msdn.microsoft.com/abhinaba/2009/03/02/back-to-basics-generational-garbage-collection/
https://stackoverflow.com/a/19155441/3850881