This is a creation in
Article, where the information may have evolved or changed.
Memory allocation is related to garbage collection, where we can look at memory allocations first.
Garbage collection is more complicated than that.
At first, the rain marks greatly said several basic strategies:
- Each time a chunk of memory (such as 1MB) is requested from the operating system to reduce system calls.
- The large chunks of memory that are requested are pre-cut into small chunks to form a linked list.
- When allocating memory for an object, simply extract a small chunk from the list of appropriate sizes.
- When the object memory is reclaimed, the small block of memory is returned to the original linked list for reuse.
- If there is too much idle memory, try to return some memory to the operating system, reducing memory overhead.
There are two concepts mentioned.
Span: is a list of 1 of chunks of memory that are cut into small chunks.
Object: That's the small piece.
Although span is graded according to the size of the small block, it actually takes a more flexible strategy, which may lend a portion of a larger span list to a smaller size span under the necessary conditions and try to merge adjacent spans when actually merging.
Golang directly uses Tcmalloc's mature architecture.
Cache Central Heap
This is a level three cache.
The cache is the p inside each Golang to make one, providing a lock-free distribution.
Then central, based on the size of the sizeclass, divides all medium objects into levels, and then it does one level of the cache, reducing the amount of computation.
The heap is the last cache, where recycling and mmap applications are initiated.
Then the rain marks give the diagram a description of the memory distribution as well as the initialization process.
Also incidentally popularized the inline optimization. Some simple function blocks may be optimized, which are allocated from the heap, but the stack is allocated ...
The logic of the cache part:
You can see from the code that Tiny&large object does a specific processing. Tiny is using the classsize=2 span, and then uses as much space as possible, hoping that an object can be reused several times. Use Cache.tinyoffset, Cache.tiny to control.
Large objects use heap allocations directly:
It also introduces a
Systemstack (func () {
s = largealloc (size, UInt32 (flags))
}) This allocation function, which uses the system stack to run, guarantees global synchronization.
The logic of the mcentral part:
This guy also has two small caches inside.
That's a little bit of a dick.
Careful look at the code can know, mcentral details of the strategy is still a lot of, such as first consider nonempty then consider empty, use empty first to a msweep to try ... It's not the only way to find the heap ...
The logic of the MHEAP part:
Consistent with the expected, as the last level of caching. will consider their own free, not to consider applying to the system. Inside the Freelarge is a list of links in the absence of the time, will use Freelarge, sequentially traverse the list to find the most appropriate (in larger than the target size of the smallest) freelarge.
#
#
Recovery
Come up on a review: recycling does not stare at object but the entire span.
It is probably traversing span to merge the unreachable object into Freelist, and if all objects have been reclaimed, the memory is returned to the heap. Details section, where it will consider merging with the right-hand span.
Release
The entrance here is Sysmon initiated. Every 5 minutes.
Probably just take out the span list of free and freelarge in the heap and kill it.
The details are madvise used here to improve performance in some scenarios.
Other
It's probably about four pieces of the system that also require garbage collection.
They also have a level two cache inside themselves.
Here is relatively simple, is the fix size, no span, object, ClassSize, the first level with a chunk, but also a list of reuse ... The second level is the use of chunk.
There is also a function of what record.
It is probably to improve the convenience of the span of an array type of H_spans, and then under certain conditions to trigger the expansion, each expansion of A*3/2 +1.